sync-buildbot.js should update the list of tests and platforms associated with a...
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jun 2016 20:43:01 +0000 (20:43 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 8 Jun 2016 20:43:01 +0000 (20:43 +0000)
https://bugs.webkit.org/show_bug.cgi?id=158406

Reviewed by Chris Dumez.

Add /api/update-triggerable and a test for it, which were supposed to be added in r201718
but for which I forgot to run svn add.

* public/api/update-triggerable.php: Added.
(main):
* server-tests/api-update-triggerable.js: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@201828 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Websites/perf.webkit.org/ChangeLog
Websites/perf.webkit.org/public/api/update-triggerable.php [new file with mode: 0644]
Websites/perf.webkit.org/server-tests/api-update-triggerable.js [new file with mode: 0644]

index a949a4e..31fbd1f 100644 (file)
@@ -1,3 +1,17 @@
+2016-06-08  Ryosuke Niwa  <rniwa@webkit.org>
+
+        sync-buildbot.js should update the list of tests and platforms associated with a triggerable
+        https://bugs.webkit.org/show_bug.cgi?id=158406
+
+        Reviewed by Chris Dumez.
+
+        Add /api/update-triggerable and a test for it, which were supposed to be added in r201718
+        but for which I forgot to run svn add.
+
+        * public/api/update-triggerable.php: Added.
+        (main):
+        * server-tests/api-update-triggerable.js: Added.
+
 2016-06-07  Ryosuke Niwa  <rniwa@webkit.org>
 
         Build fix after r201739. attachShadow was throwing an exception on this component.
diff --git a/Websites/perf.webkit.org/public/api/update-triggerable.php b/Websites/perf.webkit.org/public/api/update-triggerable.php
new file mode 100644 (file)
index 0000000..c0a1f7a
--- /dev/null
@@ -0,0 +1,48 @@
+<?php
+
+require('../include/json-header.php');
+
+function main($post_data) {
+    $db = new Database;
+    if (!$db->connect())
+        exit_with_error('DatabaseConnectionFailure');
+
+    $report = json_decode($post_data, true);
+    verify_slave($db, $report);
+
+    $triggerable_name = array_get($report, 'triggerable');
+    $triggerable = $db->select_first_row('build_triggerables', 'triggerable', array('name' => $triggerable_name));
+    if (!$triggerable)
+        exit_with_error('TriggerableNotFound', array('triggerable' => $triggerable_name));
+    $triggerable_id = $triggerable['triggerable_id'];
+
+    $configurations = array_get($report, 'configurations');
+    if (!is_array($configurations))
+        exit_with_error('InvalidConfigurations', array('configurations' => $configurations));
+
+    foreach ($configurations as $entry) {
+        if (!is_array($entry) || !array_key_exists('test', $entry) || !array_key_exists('platform', $entry))
+            exit_with_error('InvalidConfigurationEntry', array('configurationEntry' => $entry));
+    }
+
+    $db->begin_transaction();
+    if ($db->query_and_get_affected_rows('DELETE FROM triggerable_configurations WHERE trigconfig_triggerable = $1', array($triggerable_id)) === false) {
+        $db->rollback_transaction();
+        exit_with_error('FailedToDeleteExistingConfigurations', array('triggerable' => $triggerable_id));
+    }
+
+    foreach ($configurations as $entry) {
+        $config_info = array('test' => $entry['test'], 'platform' => $entry['platform'], 'triggerable' => $triggerable_id);
+        if (!$db->insert_row('triggerable_configurations', 'trigconfig', $config_info, null)) {
+            $db->rollback_transaction();
+            exit_with_error('FailedToInsertConfiguration', array('entry' => $entry));
+        }
+    }
+
+    $db->commit_transaction();
+    exit_with_success();
+}
+
+main($HTTP_RAW_POST_DATA);
+
+?>
diff --git a/Websites/perf.webkit.org/server-tests/api-update-triggerable.js b/Websites/perf.webkit.org/server-tests/api-update-triggerable.js
new file mode 100644 (file)
index 0000000..8c13bea
--- /dev/null
@@ -0,0 +1,125 @@
+'use strict';
+
+const assert = require('assert');
+
+require('../tools/js/v3-models.js');
+
+const TestServer = require('./resources/test-server.js');
+const MockData = require('./resources/mock-data.js');
+const addSlaveForReport = require('./resources/common-operations.js').addSlaveForReport;
+const connectToDatabaseInEveryTest = require('./resources/common-operations.js').connectToDatabaseInEveryTest;
+
+describe('/api/update-triggerable/', function () {
+    this.timeout(1000);
+    TestServer.inject();
+    connectToDatabaseInEveryTest();
+
+    const emptyUpdate = {
+        'slaveName': 'someSlave',
+        'slavePassword': 'somePassword',
+        'triggerable': 'build-webkit',
+        'configurations': [],
+    };
+
+    const smallUpdate = {
+        'slaveName': 'someSlave',
+        'slavePassword': 'somePassword',
+        'triggerable': 'build-webkit',
+        'configurations': [
+            {test: MockData.someTestId(), platform: MockData.somePlatformId()}
+        ],
+    };
+
+    it('should reject when slave name is missing', function (done) {
+        TestServer.remoteAPI().postJSON('/api/update-triggerable/', {}).then(function (response) {
+            assert.equal(response['status'], 'MissingSlaveName');
+            done();
+        }).catch(done);
+    });
+
+    it('should reject when there are no slaves', function (done) {
+        const update = {slaveName: emptyUpdate.slaveName, slavePassword: emptyUpdate.slavePassword};
+        TestServer.remoteAPI().postJSON('/api/update-triggerable/', update).then(function (response) {
+            assert.equal(response['status'], 'SlaveNotFound');
+            done();
+        }).catch(done);
+    });
+
+    it('should reject when the slave password doesn\'t match', function (done) {
+        MockData.addMockData(TestServer.database()).then(function () {
+            return addSlaveForReport(emptyUpdate);
+        }).then(function () {
+            const report = {slaveName: emptyUpdate.slaveName, slavePassword: 'badPassword'};
+            return TestServer.remoteAPI().postJSON('/api/update-triggerable/', emptyUpdate);
+        }).then(function (response) {
+            assert.equal(response['status'], 'OK');
+            done();
+        }).catch(done);
+    });
+
+    it('should accept an empty report', function (done) {
+        MockData.addMockData(TestServer.database()).then(function () {
+            return addSlaveForReport(emptyUpdate);
+        }).then(function () {
+            return TestServer.remoteAPI().postJSON('/api/update-triggerable/', emptyUpdate);
+        }).then(function (response) {
+            assert.equal(response['status'], 'OK');
+            done();
+        }).catch(done);
+    });
+
+    it('delete existing configurations when accepting an empty report', function (done) {
+        const db = TestServer.database();
+        MockData.addMockData(db).then(function () {
+            return Promise.all([
+                addSlaveForReport(emptyUpdate),
+                db.insert('triggerable_configurations',
+                    {'triggerable': 1 /* build-webkit */, 'test': MockData.someTestId(), 'platform': MockData.somePlatformId()})
+            ]);
+        }).then(function () {
+            return TestServer.remoteAPI().postJSON('/api/update-triggerable/', emptyUpdate);
+        }).then(function (response) {
+            assert.equal(response['status'], 'OK');
+            return db.selectAll('triggerable_configurations', 'test');
+        }).then(function (rows) {
+            assert.equal(rows.length, 0);
+            done();
+        }).catch(done);
+    });
+
+    it('should add configurations in the update', function (done) {
+        const db = TestServer.database();
+        MockData.addMockData(db).then(function () {
+            return addSlaveForReport(smallUpdate);
+        }).then(function () {
+            return TestServer.remoteAPI().postJSON('/api/update-triggerable/', smallUpdate);
+        }).then(function (response) {
+            assert.equal(response['status'], 'OK');
+            return db.selectAll('triggerable_configurations', 'test');
+        }).then(function (rows) {
+            assert.equal(rows.length, 1);
+            assert.equal(rows[0]['test'], smallUpdate.configurations[0]['test']);
+            assert.equal(rows[0]['platform'], smallUpdate.configurations[0]['platform']);
+            done();
+        }).catch(done);
+    });
+
+    it('should reject when a configuration is malformed', function (done) {
+        const db = TestServer.database();
+        MockData.addMockData(db).then(function () {
+            return addSlaveForReport(smallUpdate);
+        }).then(function () {
+            const update = {
+                'slaveName': 'someSlave',
+                'slavePassword': 'somePassword',
+                'triggerable': 'build-webkit',
+                'configurations': [{}],
+            };
+            return TestServer.remoteAPI().postJSON('/api/update-triggerable/', update);
+        }).then(function (response) {
+            assert.equal(response['status'], 'InvalidConfigurationEntry');
+            done();
+        }).catch(done);
+    });
+
+});