<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[214287] trunk/Websites/perf.webkit.org</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/214287">214287</a></dd>
<dt>Author</dt> <dd>rniwa@webkit.org</dd>
<dt>Date</dt> <dd>2017-03-22 17:27:01 -0700 (Wed, 22 Mar 2017)</dd>
</dl>
<h3>Log Message</h3>
<pre>/api/uploaded-file should return createdAt as a POSIX timestamp
https://bugs.webkit.org/show_bug.cgi?id=169980
Rubber-stamped by Antti Koivisto.
Call Database::to_js_time on createdAt to return it as a POSIX timestamp.
* public/include/uploaded-file-helpers.php:
(format_uploaded_file): Fixed the bug.
* server-tests/api-manifest-tests.js: Renamed from api-manifest.js.
* server-tests/api-uploaded-file-tests.js: Renamed from api-uploaded-file.js. Added a test case.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgChangeLog">trunk/Websites/perf.webkit.org/ChangeLog</a></li>
<li><a href="#trunkWebsitesperfwebkitorgpublicincludeuploadedfilehelpersphp">trunk/Websites/perf.webkit.org/public/include/uploaded-file-helpers.php</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapimanifesttestsjs">trunk/Websites/perf.webkit.org/server-tests/api-manifest-tests.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapiuploadedfiletestsjs">trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file-tests.js</a></li>
</ul>
<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapimanifestjs">trunk/Websites/perf.webkit.org/server-tests/api-manifest.js</a></li>
<li><a href="#trunkWebsitesperfwebkitorgservertestsapiuploadedfilejs">trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file.js</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkWebsitesperfwebkitorgChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/ChangeLog (214286 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/ChangeLog        2017-03-23 00:16:37 UTC (rev 214286)
+++ trunk/Websites/perf.webkit.org/ChangeLog        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -1,5 +1,19 @@
</span><span class="cx"> 2017-03-22 Ryosuke Niwa <rniwa@webkit.org>
</span><span class="cx">
</span><ins>+ /api/uploaded-file should return createdAt as a POSIX timestamp
+ https://bugs.webkit.org/show_bug.cgi?id=169980
+
+ Rubber-stamped by Antti Koivisto.
+
+ Call Database::to_js_time on createdAt to return it as a POSIX timestamp.
+
+ * public/include/uploaded-file-helpers.php:
+ (format_uploaded_file): Fixed the bug.
+ * server-tests/api-manifest-tests.js: Renamed from api-manifest.js.
+ * server-tests/api-uploaded-file-tests.js: Renamed from api-uploaded-file.js. Added a test case.
+
+2017-03-22 Ryosuke Niwa <rniwa@webkit.org>
+
</ins><span class="cx"> UploadedFile should support a callback for upload progress
</span><span class="cx"> https://bugs.webkit.org/show_bug.cgi?id=169977
</span><span class="cx">
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgpublicincludeuploadedfilehelpersphp"></a>
<div class="modfile"><h4>Modified: trunk/Websites/perf.webkit.org/public/include/uploaded-file-helpers.php (214286 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/public/include/uploaded-file-helpers.php        2017-03-23 00:16:37 UTC (rev 214286)
+++ trunk/Websites/perf.webkit.org/public/include/uploaded-file-helpers.php        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -5,7 +5,7 @@
</span><span class="cx"> return array(
</span><span class="cx"> 'id' => $file_row['file_id'],
</span><span class="cx"> 'size' => $file_row['file_size'],
</span><del>- 'createdAt' => $file_row['file_created_at'],
</del><ins>+ 'createdAt' => Database::to_js_time($file_row['file_created_at']),
</ins><span class="cx"> 'mime' => $file_row['file_mime'],
</span><span class="cx"> 'filename' => $file_row['file_filename'],
</span><span class="cx"> 'author' => $file_row['file_author'],
</span></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapimanifesttestsjsfromrev214286trunkWebsitesperfwebkitorgservertestsapimanifestjs"></a>
<div class="copfile"><h4>Copied: trunk/Websites/perf.webkit.org/server-tests/api-manifest-tests.js (from rev 214286, trunk/Websites/perf.webkit.org/server-tests/api-manifest.js) (0 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-manifest-tests.js         (rev 0)
+++ trunk/Websites/perf.webkit.org/server-tests/api-manifest-tests.js        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -0,0 +1,340 @@
</span><ins>+'use strict';
+
+const assert = require('assert');
+
+require('../tools/js/v3-models.js');
+
+const MockData = require('./resources/mock-data.js');
+const TestServer = require('./resources/test-server.js');
+const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
+
+describe('/api/manifest', function () {
+ prepareServerTest(this);
+
+ it("should generate an empty manifest when database is empty", () => {
+ return TestServer.remoteAPI().getJSON('/api/manifest').then((manifest) => {
+ assert.deepEqual(Object.keys(manifest).sort(), ['all', 'bugTrackers', 'builders', 'dashboard', 'dashboards',
+ 'elapsedTime', 'fileUploadSizeLimit', 'metrics', 'repositories', 'siteTitle', 'status', 'summaryPages', 'tests', 'triggerables']);
+
+ assert.equal(typeof(manifest.elapsedTime), 'number');
+ delete manifest.elapsedTime;
+
+ assert.deepStrictEqual(manifest, {
+ siteTitle: TestServer.testConfig().siteTitle,
+ all: {},
+ bugTrackers: {},
+ builders: {},
+ dashboard: {},
+ dashboards: {},
+ fileUploadSizeLimit: 2097152, // 2MB during testing.
+ metrics: {},
+ repositories: {},
+ tests: {},
+ triggerables: {},
+ summaryPages: [],
+ status: 'OK'
+ });
+ });
+ });
+
+ const bugzillaData = {id: 1, name: 'Bugzilla', bug_url: 'https://webkit.org/b/$number', new_bug_url: 'https://bugs.webkit.org/'};
+ const radarData = {id: 2, name: 'Radar'};
+
+ it("should generate manifest with bug trackers without repositories", () => {
+ return TestServer.database().insert('bug_trackers', bugzillaData).then(() => {
+ return TestServer.remoteAPI().getJSON('/api/manifest');
+ }).then((content) => {
+ assert.deepEqual(content.bugTrackers, {1: {name: 'Bugzilla', bugUrl: 'https://webkit.org/b/$number',
+ newBugUrl: 'https://bugs.webkit.org/', repositories: null}});
+
+ let manifest = Manifest._didFetchManifest(content);
+ let tracker = BugTracker.findById(1);
+ assert(tracker);
+ assert.equal(tracker.name(), 'Bugzilla');
+ assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
+ assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
+ });
+ });
+
+ it("should generate manifest with bug trackers and repositories", () => {
+ let db = TestServer.database();
+ return Promise.all([
+ db.insert('bug_trackers', bugzillaData),
+ db.insert('bug_trackers', radarData),
+ db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
+ db.insert('repositories', {id: 9, name: 'OS X'}),
+ db.insert('repositories', {id: 22, name: 'iOS'}),
+ db.insert('tracker_repositories', {tracker: bugzillaData.id, repository: 11}),
+ db.insert('tracker_repositories', {tracker: radarData.id, repository: 9}),
+ db.insert('tracker_repositories', {tracker: radarData.id, repository: 22}),
+ ]).then(() => {
+ return TestServer.remoteAPI().getJSON('/api/manifest');
+ }).then((content) => {
+ let manifest = Manifest._didFetchManifest(content);
+
+ let webkit = Repository.findById(11);
+ assert(webkit);
+ assert.equal(webkit.name(), 'WebKit');
+ assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
+
+ let osx = Repository.findById(9);
+ assert(osx);
+ assert.equal(osx.name(), 'OS X');
+
+ let ios = Repository.findById(22);
+ assert(ios);
+ assert.equal(ios.name(), 'iOS');
+
+ let tracker = BugTracker.findById(1);
+ assert(tracker);
+ assert.equal(tracker.name(), 'Bugzilla');
+ assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
+ assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
+ assert.deepEqual(tracker.repositories(), [webkit]);
+
+ tracker = BugTracker.findById(2);
+ assert(tracker);
+ assert.equal(tracker.name(), 'Radar');
+ assert.deepEqual(Repository.sortByName(tracker.repositories()), [osx, ios]);
+ });
+ });
+
+ it("should generate manifest with builders", () => {
+ let db = TestServer.database();
+ return Promise.all([
+ db.insert('builders', {id: 1, name: 'SomeBuilder', password_hash: 'a',
+ build_url: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'}),
+ db.insert('builders', {id: 2, name: 'SomeOtherBuilder', password_hash: 'b'})
+ ]).then(() => {
+ return TestServer.remoteAPI().getJSON('/api/manifest');
+ }).then((content) => {
+ assert.deepEqual(content.builders, {
+ '1': {name: 'SomeBuilder', buildUrl: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'},
+ '2': {name: 'SomeOtherBuilder', buildUrl: null}
+ });
+
+ let manifest = Manifest._didFetchManifest(content);
+
+ let builder = Builder.findById(1);
+ assert(builder);
+ assert.equal(builder.name(), 'SomeBuilder');
+ assert.equal(builder.urlForBuild(123), 'https://build.webkit.org/builders/SomeBuilder/build/123');
+
+ builder = Builder.findById(2);
+ assert(builder);
+ assert.equal(builder.name(), 'SomeOtherBuilder');
+ assert.equal(builder.urlForBuild(123), null);
+ });
+ });
+
+ it("should generate manifest with tests, metrics, and platforms", () => {
+ let db = TestServer.database();
+ return Promise.all([
+ db.insert('tests', {id: 1, name: 'SomeTest'}),
+ db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
+ db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
+ db.insert('tests', {id: 4, name: 'GrandChild', parent: 3}),
+ db.insert('aggregators', {id: 200, name: 'Total'}),
+ db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
+ db.insert('test_metrics', {id: 6, test: 2, name: 'Time', aggregator: 200}),
+ db.insert('test_metrics', {id: 7, test: 2, name: 'Malloc', aggregator: 200}),
+ db.insert('test_metrics', {id: 8, test: 3, name: 'Time'}),
+ db.insert('test_metrics', {id: 9, test: 4, name: 'Time'}),
+ db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
+ db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
+ db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 102, metric: 6, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 103, metric: 7, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 104, metric: 8, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 105, metric: 9, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 106, metric: 5, platform: 23, type: 'current'}),
+ db.insert('test_configurations', {id: 107, metric: 5, platform: 23, type: 'baseline'}),
+ ]).then(() => {
+ return TestServer.remoteAPI().getJSON('/api/manifest');
+ }).then((content) => {
+ assert.deepEqual(content.tests, {
+ "1": {"name": "SomeTest", "parentId": null, "url": null},
+ "2": {"name": "SomeOtherTest", "parentId": null, "url": null},
+ "3": {"name": "ChildTest", "parentId": "1", "url": null},
+ "4": {"name": "GrandChild", "parentId": "3", "url": null},
+ });
+
+ assert.deepEqual(content.metrics, {
+ '5': {name: 'Time', test: '1', aggregator: null},
+ '6': {name: 'Time', test: '2', aggregator: 'Total'},
+ '7': {name: 'Malloc', test: '2', aggregator: 'Total'},
+ '8': {name: 'Time', test: '3', aggregator: null},
+ '9': {name: 'Time', test: '4', aggregator: null},
+ });
+
+ let manifest = Manifest._didFetchManifest(content);
+
+ let someTest = Test.findById(1);
+ let someTestMetric = Metric.findById(5);
+ let someOtherTest = Test.findById(2);
+ let someOtherTestTime = Metric.findById(6);
+ let someOtherTestMalloc = Metric.findById(7);
+ let childTest = Test.findById(3);
+ let childTestMetric = Metric.findById(8);
+ let grandChildTest = Test.findById(4);
+ let ios9iphone5s = Platform.findById(23);
+ let mavericks = Platform.findById(46);
+ assert(someTest);
+ assert(someTestMetric);
+ assert(someOtherTest);
+ assert(someOtherTestTime);
+ assert(someOtherTestMalloc);
+ assert(childTest);
+ assert(childTestMetric);
+ assert(grandChildTest);
+ assert(ios9iphone5s);
+ assert(mavericks);
+
+ assert.equal(mavericks.name(), 'Trunk Mavericks');
+ assert(mavericks.hasTest(someTest));
+ assert(mavericks.hasTest(someOtherTest));
+ assert(mavericks.hasTest(childTest));
+ assert(mavericks.hasTest(grandChildTest));
+ assert(mavericks.hasMetric(someTestMetric));
+ assert(mavericks.hasMetric(someOtherTestTime));
+ assert(mavericks.hasMetric(someOtherTestMalloc));
+ assert(mavericks.hasMetric(childTestMetric));
+
+ assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
+ assert(ios9iphone5s.hasTest(someTest));
+ assert(!ios9iphone5s.hasTest(someOtherTest));
+ assert(!ios9iphone5s.hasTest(childTest));
+ assert(!ios9iphone5s.hasTest(grandChildTest));
+ assert(ios9iphone5s.hasMetric(someTestMetric));
+ assert(!ios9iphone5s.hasMetric(someOtherTestTime));
+ assert(!ios9iphone5s.hasMetric(someOtherTestMalloc));
+ assert(!ios9iphone5s.hasMetric(childTestMetric));
+
+ assert.equal(someTest.name(), 'SomeTest');
+ assert.equal(someTest.parentTest(), null);
+ assert.deepEqual(someTest.path(), [someTest]);
+ assert(!someTest.onlyContainsSingleMetric());
+ assert.deepEqual(someTest.childTests(), [childTest]);
+ assert.deepEqual(someTest.metrics(), [someTestMetric]);
+
+ assert.equal(someTestMetric.name(), 'Time');
+ assert.equal(someTestMetric.aggregatorName(), null);
+ assert.equal(someTestMetric.label(), 'Time');
+ assert.deepEqual(someTestMetric.childMetrics(), childTest.metrics());
+ assert.equal(someTestMetric.fullName(), 'SomeTest : Time');
+
+ assert.equal(someOtherTest.name(), 'SomeOtherTest');
+ assert.equal(someOtherTest.parentTest(), null);
+ assert.deepEqual(someOtherTest.path(), [someOtherTest]);
+ assert(!someOtherTest.onlyContainsSingleMetric());
+ assert.deepEqual(someOtherTest.childTests(), []);
+ assert.equal(someOtherTest.metrics().length, 2);
+ assert.equal(someOtherTest.metrics()[0].name(), 'Time');
+ assert.equal(someOtherTest.metrics()[0].aggregatorName(), 'Total');
+ assert.equal(someOtherTest.metrics()[0].label(), 'Time : Total');
+ assert.equal(someOtherTest.metrics()[0].childMetrics().length, 0);
+ assert.equal(someOtherTest.metrics()[0].fullName(), 'SomeOtherTest : Time : Total');
+ assert.equal(someOtherTest.metrics()[1].name(), 'Malloc');
+ assert.equal(someOtherTest.metrics()[1].aggregatorName(), 'Total');
+ assert.equal(someOtherTest.metrics()[1].label(), 'Malloc : Total');
+ assert.equal(someOtherTest.metrics()[1].childMetrics().length, 0);
+ assert.equal(someOtherTest.metrics()[1].fullName(), 'SomeOtherTest : Malloc : Total');
+
+ assert.equal(childTest.name(), 'ChildTest');
+ assert.equal(childTest.parentTest(), someTest);
+ assert.deepEqual(childTest.path(), [someTest, childTest]);
+ assert(!childTest.onlyContainsSingleMetric());
+ assert.deepEqual(childTest.childTests(), [grandChildTest]);
+ assert.equal(childTest.metrics().length, 1);
+ assert.equal(childTest.metrics()[0].label(), 'Time');
+ assert.equal(childTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest : Time');
+
+ assert.equal(grandChildTest.name(), 'GrandChild');
+ assert.equal(grandChildTest.parentTest(), childTest);
+ assert.deepEqual(grandChildTest.path(), [someTest, childTest, grandChildTest]);
+ assert(grandChildTest.onlyContainsSingleMetric());
+ assert.deepEqual(grandChildTest.childTests(), []);
+ assert.equal(grandChildTest.metrics().length, 1);
+ assert.equal(grandChildTest.metrics()[0].label(), 'Time');
+ assert.equal(grandChildTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest \u220B GrandChild : Time');
+ });
+ });
+
+ it("should generate manifest with triggerables", () => {
+ let db = TestServer.database();
+ return Promise.all([
+ db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
+ db.insert('repositories', {id: 9, name: 'OS X'}),
+ db.insert('repositories', {id: 101, name: 'WebKit', owner: 9, url: 'https://trac.webkit.org/$1'}),
+ db.insert('build_triggerables', {id: 200, name: 'build.webkit.org'}),
+ db.insert('build_triggerables', {id: 201, name: 'ios-build.webkit.org'}),
+ db.insert('tests', {id: 1, name: 'SomeTest'}),
+ db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
+ db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
+ db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
+ db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
+ db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
+ db.insert('test_metrics', {id: 8, test: 2, name: 'FrameRate'}),
+ db.insert('test_metrics', {id: 9, test: 3, name: 'Time'}),
+ db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 102, metric: 8, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 103, metric: 9, platform: 46, type: 'current'}),
+ db.insert('test_configurations', {id: 104, metric: 5, platform: 23, type: 'current'}),
+ db.insert('test_configurations', {id: 105, metric: 8, platform: 23, type: 'current'}),
+ db.insert('test_configurations', {id: 106, metric: 9, platform: 23, type: 'current'}),
+ db.insert('triggerable_repositories', {triggerable: 200, repository: 11}),
+ db.insert('triggerable_repositories', {triggerable: 201, repository: 11}),
+ db.insert('triggerable_configurations', {triggerable: 200, test: 1, platform: 46}),
+ db.insert('triggerable_configurations', {triggerable: 200, test: 2, platform: 46}),
+ db.insert('triggerable_configurations', {triggerable: 201, test: 1, platform: 23}),
+ db.insert('triggerable_configurations', {triggerable: 201, test: 2, platform: 23}),
+ ]).then(() => {
+ return Manifest.fetch();
+ }).then(() => {
+ let webkit = Repository.findById(11);
+ assert.equal(webkit.name(), 'WebKit');
+ assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
+
+ let osWebkit1 = Repository.findById(101);
+ assert.equal(osWebkit1.name(), 'WebKit');
+ assert.equal(osWebkit1.owner(), 9);
+ assert.equal(osWebkit1.urlForRevision(123), 'https://trac.webkit.org/123');
+
+ let osx = Repository.findById(9);
+ assert.equal(osx.name(), 'OS X');
+
+ let someTest = Test.findById(1);
+ assert.equal(someTest.name(), 'SomeTest');
+
+ let someOtherTest = Test.findById(2);
+ assert.equal(someOtherTest.name(), 'SomeOtherTest');
+
+ let childTest = Test.findById(3);
+ assert.equal(childTest.name(), 'ChildTest');
+
+ let ios9iphone5s = Platform.findById(23);
+ assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
+
+ let mavericks = Platform.findById(46);
+ assert.equal(mavericks.name(), 'Trunk Mavericks');
+
+ assert.equal(Triggerable.all().length, 2);
+
+ let osxTriggerable = Triggerable.findByTestConfiguration(someTest, mavericks);
+ assert.equal(osxTriggerable.name(), 'build.webkit.org');
+ assert.deepEqual(osxTriggerable.acceptedRepositories(), [webkit]);
+
+ assert.equal(Triggerable.findByTestConfiguration(someOtherTest, mavericks), osxTriggerable);
+ assert.equal(Triggerable.findByTestConfiguration(childTest, mavericks), osxTriggerable);
+
+ let iosTriggerable = Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s);
+ assert.notEqual(iosTriggerable, osxTriggerable);
+ assert.equal(iosTriggerable.name(), 'ios-build.webkit.org');
+ assert.deepEqual(iosTriggerable.acceptedRepositories(), [webkit]);
+
+ assert.equal(Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s), iosTriggerable);
+ assert.equal(Triggerable.findByTestConfiguration(childTest, ios9iphone5s), iosTriggerable);
+ });
+ });
+
+});
</ins></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapimanifestjs"></a>
<div class="delfile"><h4>Deleted: trunk/Websites/perf.webkit.org/server-tests/api-manifest.js (214286 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-manifest.js        2017-03-23 00:16:37 UTC (rev 214286)
+++ trunk/Websites/perf.webkit.org/server-tests/api-manifest.js        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -1,340 +0,0 @@
</span><del>-'use strict';
-
-const assert = require('assert');
-
-require('../tools/js/v3-models.js');
-
-const MockData = require('./resources/mock-data.js');
-const TestServer = require('./resources/test-server.js');
-const prepareServerTest = require('./resources/common-operations.js').prepareServerTest;
-
-describe('/api/manifest', function () {
- prepareServerTest(this);
-
- it("should generate an empty manifest when database is empty", () => {
- return TestServer.remoteAPI().getJSON('/api/manifest').then((manifest) => {
- assert.deepEqual(Object.keys(manifest).sort(), ['all', 'bugTrackers', 'builders', 'dashboard', 'dashboards',
- 'elapsedTime', 'fileUploadSizeLimit', 'metrics', 'repositories', 'siteTitle', 'status', 'summaryPages', 'tests', 'triggerables']);
-
- assert.equal(typeof(manifest.elapsedTime), 'number');
- delete manifest.elapsedTime;
-
- assert.deepStrictEqual(manifest, {
- siteTitle: TestServer.testConfig().siteTitle,
- all: {},
- bugTrackers: {},
- builders: {},
- dashboard: {},
- dashboards: {},
- fileUploadSizeLimit: 2097152, // 2MB during testing.
- metrics: {},
- repositories: {},
- tests: {},
- triggerables: {},
- summaryPages: [],
- status: 'OK'
- });
- });
- });
-
- const bugzillaData = {id: 1, name: 'Bugzilla', bug_url: 'https://webkit.org/b/$number', new_bug_url: 'https://bugs.webkit.org/'};
- const radarData = {id: 2, name: 'Radar'};
-
- it("should generate manifest with bug trackers without repositories", () => {
- return TestServer.database().insert('bug_trackers', bugzillaData).then(() => {
- return TestServer.remoteAPI().getJSON('/api/manifest');
- }).then((content) => {
- assert.deepEqual(content.bugTrackers, {1: {name: 'Bugzilla', bugUrl: 'https://webkit.org/b/$number',
- newBugUrl: 'https://bugs.webkit.org/', repositories: null}});
-
- let manifest = Manifest._didFetchManifest(content);
- let tracker = BugTracker.findById(1);
- assert(tracker);
- assert.equal(tracker.name(), 'Bugzilla');
- assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
- assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
- });
- });
-
- it("should generate manifest with bug trackers and repositories", () => {
- let db = TestServer.database();
- return Promise.all([
- db.insert('bug_trackers', bugzillaData),
- db.insert('bug_trackers', radarData),
- db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
- db.insert('repositories', {id: 9, name: 'OS X'}),
- db.insert('repositories', {id: 22, name: 'iOS'}),
- db.insert('tracker_repositories', {tracker: bugzillaData.id, repository: 11}),
- db.insert('tracker_repositories', {tracker: radarData.id, repository: 9}),
- db.insert('tracker_repositories', {tracker: radarData.id, repository: 22}),
- ]).then(() => {
- return TestServer.remoteAPI().getJSON('/api/manifest');
- }).then((content) => {
- let manifest = Manifest._didFetchManifest(content);
-
- let webkit = Repository.findById(11);
- assert(webkit);
- assert.equal(webkit.name(), 'WebKit');
- assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
-
- let osx = Repository.findById(9);
- assert(osx);
- assert.equal(osx.name(), 'OS X');
-
- let ios = Repository.findById(22);
- assert(ios);
- assert.equal(ios.name(), 'iOS');
-
- let tracker = BugTracker.findById(1);
- assert(tracker);
- assert.equal(tracker.name(), 'Bugzilla');
- assert.equal(tracker.bugUrl(123), 'https://webkit.org/b/123');
- assert.equal(tracker.newBugUrl(), 'https://bugs.webkit.org/');
- assert.deepEqual(tracker.repositories(), [webkit]);
-
- tracker = BugTracker.findById(2);
- assert(tracker);
- assert.equal(tracker.name(), 'Radar');
- assert.deepEqual(Repository.sortByName(tracker.repositories()), [osx, ios]);
- });
- });
-
- it("should generate manifest with builders", () => {
- let db = TestServer.database();
- return Promise.all([
- db.insert('builders', {id: 1, name: 'SomeBuilder', password_hash: 'a',
- build_url: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'}),
- db.insert('builders', {id: 2, name: 'SomeOtherBuilder', password_hash: 'b'})
- ]).then(() => {
- return TestServer.remoteAPI().getJSON('/api/manifest');
- }).then((content) => {
- assert.deepEqual(content.builders, {
- '1': {name: 'SomeBuilder', buildUrl: 'https://build.webkit.org/builders/$builderName/build/$buildNumber'},
- '2': {name: 'SomeOtherBuilder', buildUrl: null}
- });
-
- let manifest = Manifest._didFetchManifest(content);
-
- let builder = Builder.findById(1);
- assert(builder);
- assert.equal(builder.name(), 'SomeBuilder');
- assert.equal(builder.urlForBuild(123), 'https://build.webkit.org/builders/SomeBuilder/build/123');
-
- builder = Builder.findById(2);
- assert(builder);
- assert.equal(builder.name(), 'SomeOtherBuilder');
- assert.equal(builder.urlForBuild(123), null);
- });
- });
-
- it("should generate manifest with tests, metrics, and platforms", () => {
- let db = TestServer.database();
- return Promise.all([
- db.insert('tests', {id: 1, name: 'SomeTest'}),
- db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
- db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
- db.insert('tests', {id: 4, name: 'GrandChild', parent: 3}),
- db.insert('aggregators', {id: 200, name: 'Total'}),
- db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
- db.insert('test_metrics', {id: 6, test: 2, name: 'Time', aggregator: 200}),
- db.insert('test_metrics', {id: 7, test: 2, name: 'Malloc', aggregator: 200}),
- db.insert('test_metrics', {id: 8, test: 3, name: 'Time'}),
- db.insert('test_metrics', {id: 9, test: 4, name: 'Time'}),
- db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
- db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
- db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 102, metric: 6, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 103, metric: 7, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 104, metric: 8, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 105, metric: 9, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 106, metric: 5, platform: 23, type: 'current'}),
- db.insert('test_configurations', {id: 107, metric: 5, platform: 23, type: 'baseline'}),
- ]).then(() => {
- return TestServer.remoteAPI().getJSON('/api/manifest');
- }).then((content) => {
- assert.deepEqual(content.tests, {
- "1": {"name": "SomeTest", "parentId": null, "url": null},
- "2": {"name": "SomeOtherTest", "parentId": null, "url": null},
- "3": {"name": "ChildTest", "parentId": "1", "url": null},
- "4": {"name": "GrandChild", "parentId": "3", "url": null},
- });
-
- assert.deepEqual(content.metrics, {
- '5': {name: 'Time', test: '1', aggregator: null},
- '6': {name: 'Time', test: '2', aggregator: 'Total'},
- '7': {name: 'Malloc', test: '2', aggregator: 'Total'},
- '8': {name: 'Time', test: '3', aggregator: null},
- '9': {name: 'Time', test: '4', aggregator: null},
- });
-
- let manifest = Manifest._didFetchManifest(content);
-
- let someTest = Test.findById(1);
- let someTestMetric = Metric.findById(5);
- let someOtherTest = Test.findById(2);
- let someOtherTestTime = Metric.findById(6);
- let someOtherTestMalloc = Metric.findById(7);
- let childTest = Test.findById(3);
- let childTestMetric = Metric.findById(8);
- let grandChildTest = Test.findById(4);
- let ios9iphone5s = Platform.findById(23);
- let mavericks = Platform.findById(46);
- assert(someTest);
- assert(someTestMetric);
- assert(someOtherTest);
- assert(someOtherTestTime);
- assert(someOtherTestMalloc);
- assert(childTest);
- assert(childTestMetric);
- assert(grandChildTest);
- assert(ios9iphone5s);
- assert(mavericks);
-
- assert.equal(mavericks.name(), 'Trunk Mavericks');
- assert(mavericks.hasTest(someTest));
- assert(mavericks.hasTest(someOtherTest));
- assert(mavericks.hasTest(childTest));
- assert(mavericks.hasTest(grandChildTest));
- assert(mavericks.hasMetric(someTestMetric));
- assert(mavericks.hasMetric(someOtherTestTime));
- assert(mavericks.hasMetric(someOtherTestMalloc));
- assert(mavericks.hasMetric(childTestMetric));
-
- assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
- assert(ios9iphone5s.hasTest(someTest));
- assert(!ios9iphone5s.hasTest(someOtherTest));
- assert(!ios9iphone5s.hasTest(childTest));
- assert(!ios9iphone5s.hasTest(grandChildTest));
- assert(ios9iphone5s.hasMetric(someTestMetric));
- assert(!ios9iphone5s.hasMetric(someOtherTestTime));
- assert(!ios9iphone5s.hasMetric(someOtherTestMalloc));
- assert(!ios9iphone5s.hasMetric(childTestMetric));
-
- assert.equal(someTest.name(), 'SomeTest');
- assert.equal(someTest.parentTest(), null);
- assert.deepEqual(someTest.path(), [someTest]);
- assert(!someTest.onlyContainsSingleMetric());
- assert.deepEqual(someTest.childTests(), [childTest]);
- assert.deepEqual(someTest.metrics(), [someTestMetric]);
-
- assert.equal(someTestMetric.name(), 'Time');
- assert.equal(someTestMetric.aggregatorName(), null);
- assert.equal(someTestMetric.label(), 'Time');
- assert.deepEqual(someTestMetric.childMetrics(), childTest.metrics());
- assert.equal(someTestMetric.fullName(), 'SomeTest : Time');
-
- assert.equal(someOtherTest.name(), 'SomeOtherTest');
- assert.equal(someOtherTest.parentTest(), null);
- assert.deepEqual(someOtherTest.path(), [someOtherTest]);
- assert(!someOtherTest.onlyContainsSingleMetric());
- assert.deepEqual(someOtherTest.childTests(), []);
- assert.equal(someOtherTest.metrics().length, 2);
- assert.equal(someOtherTest.metrics()[0].name(), 'Time');
- assert.equal(someOtherTest.metrics()[0].aggregatorName(), 'Total');
- assert.equal(someOtherTest.metrics()[0].label(), 'Time : Total');
- assert.equal(someOtherTest.metrics()[0].childMetrics().length, 0);
- assert.equal(someOtherTest.metrics()[0].fullName(), 'SomeOtherTest : Time : Total');
- assert.equal(someOtherTest.metrics()[1].name(), 'Malloc');
- assert.equal(someOtherTest.metrics()[1].aggregatorName(), 'Total');
- assert.equal(someOtherTest.metrics()[1].label(), 'Malloc : Total');
- assert.equal(someOtherTest.metrics()[1].childMetrics().length, 0);
- assert.equal(someOtherTest.metrics()[1].fullName(), 'SomeOtherTest : Malloc : Total');
-
- assert.equal(childTest.name(), 'ChildTest');
- assert.equal(childTest.parentTest(), someTest);
- assert.deepEqual(childTest.path(), [someTest, childTest]);
- assert(!childTest.onlyContainsSingleMetric());
- assert.deepEqual(childTest.childTests(), [grandChildTest]);
- assert.equal(childTest.metrics().length, 1);
- assert.equal(childTest.metrics()[0].label(), 'Time');
- assert.equal(childTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest : Time');
-
- assert.equal(grandChildTest.name(), 'GrandChild');
- assert.equal(grandChildTest.parentTest(), childTest);
- assert.deepEqual(grandChildTest.path(), [someTest, childTest, grandChildTest]);
- assert(grandChildTest.onlyContainsSingleMetric());
- assert.deepEqual(grandChildTest.childTests(), []);
- assert.equal(grandChildTest.metrics().length, 1);
- assert.equal(grandChildTest.metrics()[0].label(), 'Time');
- assert.equal(grandChildTest.metrics()[0].fullName(), 'SomeTest \u220B ChildTest \u220B GrandChild : Time');
- });
- });
-
- it("should generate manifest with triggerables", () => {
- let db = TestServer.database();
- return Promise.all([
- db.insert('repositories', {id: 11, name: 'WebKit', url: 'https://trac.webkit.org/$1'}),
- db.insert('repositories', {id: 9, name: 'OS X'}),
- db.insert('repositories', {id: 101, name: 'WebKit', owner: 9, url: 'https://trac.webkit.org/$1'}),
- db.insert('build_triggerables', {id: 200, name: 'build.webkit.org'}),
- db.insert('build_triggerables', {id: 201, name: 'ios-build.webkit.org'}),
- db.insert('tests', {id: 1, name: 'SomeTest'}),
- db.insert('tests', {id: 2, name: 'SomeOtherTest'}),
- db.insert('tests', {id: 3, name: 'ChildTest', parent: 1}),
- db.insert('platforms', {id: 23, name: 'iOS 9 iPhone 5s'}),
- db.insert('platforms', {id: 46, name: 'Trunk Mavericks'}),
- db.insert('test_metrics', {id: 5, test: 1, name: 'Time'}),
- db.insert('test_metrics', {id: 8, test: 2, name: 'FrameRate'}),
- db.insert('test_metrics', {id: 9, test: 3, name: 'Time'}),
- db.insert('test_configurations', {id: 101, metric: 5, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 102, metric: 8, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 103, metric: 9, platform: 46, type: 'current'}),
- db.insert('test_configurations', {id: 104, metric: 5, platform: 23, type: 'current'}),
- db.insert('test_configurations', {id: 105, metric: 8, platform: 23, type: 'current'}),
- db.insert('test_configurations', {id: 106, metric: 9, platform: 23, type: 'current'}),
- db.insert('triggerable_repositories', {triggerable: 200, repository: 11}),
- db.insert('triggerable_repositories', {triggerable: 201, repository: 11}),
- db.insert('triggerable_configurations', {triggerable: 200, test: 1, platform: 46}),
- db.insert('triggerable_configurations', {triggerable: 200, test: 2, platform: 46}),
- db.insert('triggerable_configurations', {triggerable: 201, test: 1, platform: 23}),
- db.insert('triggerable_configurations', {triggerable: 201, test: 2, platform: 23}),
- ]).then(() => {
- return Manifest.fetch();
- }).then(() => {
- let webkit = Repository.findById(11);
- assert.equal(webkit.name(), 'WebKit');
- assert.equal(webkit.urlForRevision(123), 'https://trac.webkit.org/123');
-
- let osWebkit1 = Repository.findById(101);
- assert.equal(osWebkit1.name(), 'WebKit');
- assert.equal(osWebkit1.owner(), 9);
- assert.equal(osWebkit1.urlForRevision(123), 'https://trac.webkit.org/123');
-
- let osx = Repository.findById(9);
- assert.equal(osx.name(), 'OS X');
-
- let someTest = Test.findById(1);
- assert.equal(someTest.name(), 'SomeTest');
-
- let someOtherTest = Test.findById(2);
- assert.equal(someOtherTest.name(), 'SomeOtherTest');
-
- let childTest = Test.findById(3);
- assert.equal(childTest.name(), 'ChildTest');
-
- let ios9iphone5s = Platform.findById(23);
- assert.equal(ios9iphone5s.name(), 'iOS 9 iPhone 5s');
-
- let mavericks = Platform.findById(46);
- assert.equal(mavericks.name(), 'Trunk Mavericks');
-
- assert.equal(Triggerable.all().length, 2);
-
- let osxTriggerable = Triggerable.findByTestConfiguration(someTest, mavericks);
- assert.equal(osxTriggerable.name(), 'build.webkit.org');
- assert.deepEqual(osxTriggerable.acceptedRepositories(), [webkit]);
-
- assert.equal(Triggerable.findByTestConfiguration(someOtherTest, mavericks), osxTriggerable);
- assert.equal(Triggerable.findByTestConfiguration(childTest, mavericks), osxTriggerable);
-
- let iosTriggerable = Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s);
- assert.notEqual(iosTriggerable, osxTriggerable);
- assert.equal(iosTriggerable.name(), 'ios-build.webkit.org');
- assert.deepEqual(iosTriggerable.acceptedRepositories(), [webkit]);
-
- assert.equal(Triggerable.findByTestConfiguration(someOtherTest, ios9iphone5s), iosTriggerable);
- assert.equal(Triggerable.findByTestConfiguration(childTest, ios9iphone5s), iosTriggerable);
- });
- });
-
-});
</del></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapiuploadedfiletestsjsfromrev214286trunkWebsitesperfwebkitorgservertestsapiuploadedfilejs"></a>
<div class="copfile"><h4>Copied: trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file-tests.js (from rev 214286, trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file.js) (0 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file-tests.js         (rev 0)
+++ trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file-tests.js        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -0,0 +1,324 @@
</span><ins>+'use strict';
+
+require('../tools/js/v3-models.js');
+
+const assert = require('assert');
+global.FormData = require('form-data');
+
+const TestServer = require('./resources/test-server.js');
+const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
+
+describe('/api/uploaded-file', function () {
+ this.timeout(5000);
+ TestServer.inject();
+
+ TemporaryFile.inject();
+
+ it('should return "InvalidArguments" when neither path nor sha256 query is set', () => {
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file').then((content) => {
+ assert.equal(content['status'], 'InvalidArguments');
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file/');
+ }).then((content) => {
+ assert.equal(content['status'], 'InvalidArguments');
+ });
+ });
+
+ it('should return 404 when there is no file with the specified ID', () => {
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file/1').then((content) => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 404);
+ });
+ });
+
+ it('should return 404 when the specified ID is not a valid integer', () => {
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file/foo').then((content) => {
+ assert(false, 'should never be reached');
+ }, (error) => {
+ assert.equal(error, 404);
+ });
+ });
+
+ it('should return the file content matching the specified file ID', () => {
+ let uploadedFile;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ uploadedFile = response['uploadedFile'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${uploadedFile['id']}`, 'GET', null, null);
+ }).then((response) => {
+ assert.equal(response.responseText, 'some content');
+ });
+ });
+
+ it('should return the file content with createdAt using POSIX timestamp in UTC', () => {
+ let uploadedFile;
+ const startTime = +Date.now();
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ uploadedFile = response['uploadedFile'];
+ console.assert(typeof(uploadedFile.createdAt) == 'number')
+ const createdAt = +new Date(uploadedFile.createdAt);
+ const endTime = +Date.now();
+ assert(startTime <= createdAt, 'createdAt should be after the time POST request was made');
+ assert(createdAt <= endTime, 'createdAt should be before the uploadedFile response had finished');
+ });
+ });
+
+ it('should return "NotFound" when the specified SHA256 is invalid', () => {
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file/?sha256=abc').then((content) => {
+ assert.equal(content['status'], 'NotFound');
+ });
+ });
+
+ it('should return "NotFound" when there is no file matching the specified SHA256 ', () => {
+ return TestServer.remoteAPI().getJSON('/api/uploaded-file/?sha256=5256ec18f11624025905d057d6befb03d77b243511ac5f77ed5e0221ce6d84b5').then((content) => {
+ assert.equal(content['status'], 'NotFound');
+ });
+ });
+
+ it('should return the meta data of the file with the specified SHA256', () => {
+ let uploadedFile;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ uploadedFile = response['uploadedFile'];
+ return TestServer.remoteAPI().getJSON(`/api/uploaded-file/?sha256=${uploadedFile['sha256']}`);
+ }).then((response) => {
+ assert.deepEqual(uploadedFile, response['uploadedFile']);
+ });
+ });
+
+ it('should return "NotFound" when the file matching the specified SHA256 had already been deleted', () => {
+ let uploadedFile;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ uploadedFile = response['uploadedFile'];
+ const db = TestServer.database();
+ return db.connect().then(() => db.query(`UPDATE uploaded_files SET file_deleted_at = now() at time zone 'utc'`));
+ }).then(() => {
+ return TestServer.remoteAPI().getJSON(`/api/uploaded-file/?sha256=${uploadedFile['sha256']}`);
+ }).then((content) => {
+ assert.equal(content['status'], 'NotFound');
+ });
+ });
+
+
+ it('should respond with ETag, Acccept-Ranges, Content-Disposition, Content-Length, and Last-Modified headers', () => {
+ let uploadedFile;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ uploadedFile = response['uploadedFile'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${uploadedFile['id']}`, 'GET', null, null);
+ }).then((response) => {
+ const headers = response.headers;
+
+ assert(Object.keys(headers).includes('etag'));
+ assert.equal(headers['etag'], uploadedFile['sha256']);
+
+ assert(Object.keys(headers).includes('accept-ranges'));
+ assert.equal(headers['accept-ranges'], 'bytes');
+
+ assert(Object.keys(headers).includes('content-disposition'));
+ assert.equal(headers['content-disposition'], `attachment; filename*=utf-8''some.dat`);
+
+ assert(Object.keys(headers).includes('content-length'));
+ assert.equal(headers['content-length'], uploadedFile['size']);
+
+ assert(Object.keys(headers).includes('last-modified'));
+ });
+ });
+
+ it('should respond with the same Last-Modified each time', () => {
+ let id;
+ let lastModified;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
+ }).then((response) => {
+ lastModified = response.headers['last-modified'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
+ }).then((response) => {
+ assert.equal(response.headers['last-modified'], lastModified);
+ });
+ });
+
+ it('should respond with Content-Range when requested after X bytes', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=5-'}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 5-11/12');
+ assert.equal(response.responseText, 'content');
+ });
+ });
+
+ it('should respond with Content-Range when requested between X-Y bytes', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=4-9'}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 4-9/12');
+ assert.equal(response.responseText, ' conte');
+ });
+ });
+
+ it('should respond with Content-Range when requested for the last X bytes', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=-4'}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 8-11/12');
+ assert.equal(response.responseText, 'tent');
+ });
+ });
+
+ it('should respond with Content-Range for the whole content when the suffix length is larger than the content', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=-100'}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 0-11/12');
+ assert.equal(response.responseText, 'some content');
+ });
+ });
+
+ it('should return 416 when the starting byte is after the file size', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=12-'}})
+ .then(() => assert(false, 'should never be reached'), (error) => assert.equal(error, 416));
+ });
+ });
+
+ it('should return 416 when the starting byte after the ending byte', () => {
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ const id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=2-1'}})
+ .then(() => assert(false, 'should never be reached'), (error) => assert.equal(error, 416));
+ });
+ });
+
+ it('should respond with Content-Range when If-Range matches the last modified date', () => {
+ let id;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
+ }).then((response) => {
+ assert.equal(response.statusCode, 200);
+ assert.equal(response.responseText, 'some content');
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
+ {headers: {'Range': 'bytes = 9-10', 'If-Range': response.headers['last-modified']}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 9-10/12');
+ assert.equal(response.responseText, 'en');
+ });
+ });
+
+ it('should respond with Content-Range when If-Range matches ETag', () => {
+ let id;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
+ }).then((response) => {
+ assert.equal(response.statusCode, 200);
+ assert.equal(response.responseText, 'some content');
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
+ {headers: {'Range': 'bytes = 9-10', 'If-Range': response.headers['etag']}});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], 'bytes 9-10/12');
+ assert.equal(response.responseText, 'en');
+ });
+ });
+
+ it('should return the full content when If-Range does not match the last modified date or ETag', () => {
+ let id;
+ return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
+ }).then((response) => {
+ assert.equal(response.statusCode, 200);
+ assert.equal(response.responseText, 'some content');
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
+ {'Range': 'bytes = 9-10', 'If-Range': 'foo'});
+ }).then((response) => {
+ assert.equal(response.statusCode, 200);
+ assert.equal(response.responseText, 'some content');
+ });
+ });
+
+ it('should respond with Content-Range across 64KB streaming chunks', () => {
+ let id;
+ const fileSize = 256 * 1024;
+ const tokens = "0123456789abcdefghijklmnopqrstuvwxyz";
+ let buffer = Buffer.allocUnsafe(fileSize);
+ for (let i = 0; i < fileSize; i++)
+ buffer[i] = Math.floor(Math.random() * 256);
+ let startByte = 63 * 1024;
+ let endByte = 128 * 1024 - 1;
+
+ let responseBufferList = [];
+ const responseHandler = (response) => {
+ response.on('data', (chunk) => responseBufferList.push(chunk));
+ };
+
+ function verifyBuffer()
+ {
+ const responseBuffer = Buffer.concat(responseBufferList);
+ for (let i = 0; i < endByte - startByte + 1; i++) {
+ const actual = responseBuffer[i];
+ const expected = buffer[startByte + i];
+ assert.equal(actual, expected, `The byte at index ${i} should be identical. Expected ${expected} but got ${actual}`);
+ }
+ }
+
+ return TemporaryFile.makeTemporaryFile('some.dat', buffer).then((stream) => {
+ return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
+ }).then((response) => {
+ id = response['uploadedFile']['id'];
+ return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
+ {headers: {'Range': `bytes = ${startByte}-${endByte}`}, responseHandler});
+ }).then((response) => {
+ const headers = response.headers;
+ assert.equal(response.statusCode, 206);
+ assert.equal(headers['content-range'], `bytes ${startByte}-${endByte}/${fileSize}`);
+ verifyBuffer();
+ });
+ });
+
+});
</ins></span></pre></div>
<a id="trunkWebsitesperfwebkitorgservertestsapiuploadedfilejs"></a>
<div class="delfile"><h4>Deleted: trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file.js (214286 => 214287)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file.js        2017-03-23 00:16:37 UTC (rev 214286)
+++ trunk/Websites/perf.webkit.org/server-tests/api-uploaded-file.js        2017-03-23 00:27:01 UTC (rev 214287)
</span><span class="lines">@@ -1,309 +0,0 @@
</span><del>-'use strict';
-
-require('../tools/js/v3-models.js');
-
-const assert = require('assert');
-global.FormData = require('form-data');
-
-const TestServer = require('./resources/test-server.js');
-const TemporaryFile = require('./resources/temporary-file.js').TemporaryFile;
-
-describe('/api/uploaded-file', function () {
- this.timeout(5000);
- TestServer.inject();
-
- TemporaryFile.inject();
-
- it('should return "InvalidArguments" when neither path nor sha256 query is set', () => {
- return TestServer.remoteAPI().getJSON('/api/uploaded-file').then((content) => {
- assert.equal(content['status'], 'InvalidArguments');
- return TestServer.remoteAPI().getJSON('/api/uploaded-file/');
- }).then((content) => {
- assert.equal(content['status'], 'InvalidArguments');
- });
- });
-
- it('should return 404 when there is no file with the specified ID', () => {
- return TestServer.remoteAPI().getJSON('/api/uploaded-file/1').then((content) => {
- assert(false, 'should never be reached');
- }, (error) => {
- assert.equal(error, 404);
- });
- });
-
- it('should return 404 when the specified ID is not a valid integer', () => {
- return TestServer.remoteAPI().getJSON('/api/uploaded-file/foo').then((content) => {
- assert(false, 'should never be reached');
- }, (error) => {
- assert.equal(error, 404);
- });
- });
-
- it('should return the file content matching the specified file ID', () => {
- let uploadedFile;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- uploadedFile = response['uploadedFile'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${uploadedFile['id']}`, 'GET', null, null);
- }).then((response) => {
- assert.equal(response.responseText, 'some content');
- });
- });
-
- it('should return "NotFound" when the specified SHA256 is invalid', () => {
- return TestServer.remoteAPI().getJSON('/api/uploaded-file/?sha256=abc').then((content) => {
- assert.equal(content['status'], 'NotFound');
- });
- });
-
- it('should return "NotFound" when there is no file matching the specified SHA256 ', () => {
- return TestServer.remoteAPI().getJSON('/api/uploaded-file/?sha256=5256ec18f11624025905d057d6befb03d77b243511ac5f77ed5e0221ce6d84b5').then((content) => {
- assert.equal(content['status'], 'NotFound');
- });
- });
-
- it('should return the meta data of the file with the specified SHA256', () => {
- let uploadedFile;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- uploadedFile = response['uploadedFile'];
- return TestServer.remoteAPI().getJSON(`/api/uploaded-file/?sha256=${uploadedFile['sha256']}`);
- }).then((response) => {
- assert.deepEqual(uploadedFile, response['uploadedFile']);
- });
- });
-
- it('should return "NotFound" when the file matching the specified SHA256 had already been deleted', () => {
- let uploadedFile;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- uploadedFile = response['uploadedFile'];
- const db = TestServer.database();
- return db.connect().then(() => db.query(`UPDATE uploaded_files SET file_deleted_at = now() at time zone 'utc'`));
- }).then(() => {
- return TestServer.remoteAPI().getJSON(`/api/uploaded-file/?sha256=${uploadedFile['sha256']}`);
- }).then((content) => {
- assert.equal(content['status'], 'NotFound');
- });
- });
-
-
- it('should respond with ETag, Acccept-Ranges, Content-Disposition, Content-Length, and Last-Modified headers', () => {
- let uploadedFile;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- uploadedFile = response['uploadedFile'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${uploadedFile['id']}`, 'GET', null, null);
- }).then((response) => {
- const headers = response.headers;
-
- assert(Object.keys(headers).includes('etag'));
- assert.equal(headers['etag'], uploadedFile['sha256']);
-
- assert(Object.keys(headers).includes('accept-ranges'));
- assert.equal(headers['accept-ranges'], 'bytes');
-
- assert(Object.keys(headers).includes('content-disposition'));
- assert.equal(headers['content-disposition'], `attachment; filename*=utf-8''some.dat`);
-
- assert(Object.keys(headers).includes('content-length'));
- assert.equal(headers['content-length'], uploadedFile['size']);
-
- assert(Object.keys(headers).includes('last-modified'));
- });
- });
-
- it('should respond with the same Last-Modified each time', () => {
- let id;
- let lastModified;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
- }).then((response) => {
- lastModified = response.headers['last-modified'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
- }).then((response) => {
- assert.equal(response.headers['last-modified'], lastModified);
- });
- });
-
- it('should respond with Content-Range when requested after X bytes', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=5-'}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 5-11/12');
- assert.equal(response.responseText, 'content');
- });
- });
-
- it('should respond with Content-Range when requested between X-Y bytes', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=4-9'}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 4-9/12');
- assert.equal(response.responseText, ' conte');
- });
- });
-
- it('should respond with Content-Range when requested for the last X bytes', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=-4'}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 8-11/12');
- assert.equal(response.responseText, 'tent');
- });
- });
-
- it('should respond with Content-Range for the whole content when the suffix length is larger than the content', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=-100'}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 0-11/12');
- assert.equal(response.responseText, 'some content');
- });
- });
-
- it('should return 416 when the starting byte is after the file size', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=12-'}})
- .then(() => assert(false, 'should never be reached'), (error) => assert.equal(error, 416));
- });
- });
-
- it('should return 416 when the starting byte after the ending byte', () => {
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- const id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null, {headers: {'Range': 'bytes=2-1'}})
- .then(() => assert(false, 'should never be reached'), (error) => assert.equal(error, 416));
- });
- });
-
- it('should respond with Content-Range when If-Range matches the last modified date', () => {
- let id;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
- }).then((response) => {
- assert.equal(response.statusCode, 200);
- assert.equal(response.responseText, 'some content');
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
- {headers: {'Range': 'bytes = 9-10', 'If-Range': response.headers['last-modified']}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 9-10/12');
- assert.equal(response.responseText, 'en');
- });
- });
-
- it('should respond with Content-Range when If-Range matches ETag', () => {
- let id;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
- }).then((response) => {
- assert.equal(response.statusCode, 200);
- assert.equal(response.responseText, 'some content');
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
- {headers: {'Range': 'bytes = 9-10', 'If-Range': response.headers['etag']}});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], 'bytes 9-10/12');
- assert.equal(response.responseText, 'en');
- });
- });
-
- it('should return the full content when If-Range does not match the last modified date or ETag', () => {
- let id;
- return TemporaryFile.makeTemporaryFile('some.dat', 'some content').then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null);
- }).then((response) => {
- assert.equal(response.statusCode, 200);
- assert.equal(response.responseText, 'some content');
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
- {'Range': 'bytes = 9-10', 'If-Range': 'foo'});
- }).then((response) => {
- assert.equal(response.statusCode, 200);
- assert.equal(response.responseText, 'some content');
- });
- });
-
- it('should respond with Content-Range across 64KB streaming chunks', () => {
- let id;
- const fileSize = 256 * 1024;
- const tokens = "0123456789abcdefghijklmnopqrstuvwxyz";
- let buffer = Buffer.allocUnsafe(fileSize);
- for (let i = 0; i < fileSize; i++)
- buffer[i] = Math.floor(Math.random() * 256);
- let startByte = 63 * 1024;
- let endByte = 128 * 1024 - 1;
-
- let responseBufferList = [];
- const responseHandler = (response) => {
- response.on('data', (chunk) => responseBufferList.push(chunk));
- };
-
- function verifyBuffer()
- {
- const responseBuffer = Buffer.concat(responseBufferList);
- for (let i = 0; i < endByte - startByte + 1; i++) {
- const actual = responseBuffer[i];
- const expected = buffer[startByte + i];
- assert.equal(actual, expected, `The byte at index ${i} should be identical. Expected ${expected} but got ${actual}`);
- }
- }
-
- return TemporaryFile.makeTemporaryFile('some.dat', buffer).then((stream) => {
- return PrivilegedAPI.sendRequest('upload-file', {newFile: stream}, {useFormData: true});
- }).then((response) => {
- id = response['uploadedFile']['id'];
- return TestServer.remoteAPI().sendHttpRequest(`/api/uploaded-file/${id}`, 'GET', null, null,
- {headers: {'Range': `bytes = ${startByte}-${endByte}`}, responseHandler});
- }).then((response) => {
- const headers = response.headers;
- assert.equal(response.statusCode, 206);
- assert.equal(headers['content-range'], `bytes ${startByte}-${endByte}/${fileSize}`);
- verifyBuffer();
- });
- });
-
-});
</del></span></pre>
</div>
</div>
</body>
</html>