summaryrefslogtreecommitdiffstats
path: root/native_client_sdk
diff options
context:
space:
mode:
authorbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 17:12:27 +0000
committerbinji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-16 17:12:27 +0000
commit20b417d88f0d3d4156c91278d9111e3a493886ec (patch)
tree93d2e147474d60c1df27e5de79dde082da32b0c6 /native_client_sdk
parent1078219ee033739693c6fee4225bb690b5aa3ab4 (diff)
downloadchromium_src-20b417d88f0d3d4156c91278d9111e3a493886ec.zip
chromium_src-20b417d88f0d3d4156c91278d9111e3a493886ec.tar.gz
chromium_src-20b417d88f0d3d4156c91278d9111e3a493886ec.tar.bz2
[NaCl SDK] Framework for adding additional tests to examples.
I've also added a test.js file to nacl_io_tests to exercise the new code. BUG=none R=sbc@chromium.org Review URL: https://codereview.chromium.org/23229002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@218030 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
-rw-r--r--native_client_sdk/src/build_tools/test.js6
-rwxr-xr-xnative_client_sdk/src/build_tools/test_projects.py21
-rwxr-xr-xnative_client_sdk/src/build_tools/test_sdk.py1
-rw-r--r--native_client_sdk/src/examples/common.js92
-rw-r--r--native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc29
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/example.js9
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/main.cc4
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc9
-rw-r--r--native_client_sdk/src/libraries/nacl_io_test/test.js18
9 files changed, 134 insertions, 55 deletions
diff --git a/native_client_sdk/src/build_tools/test.js b/native_client_sdk/src/build_tools/test.js
new file mode 100644
index 0000000..d6ba6d8
--- /dev/null
+++ b/native_client_sdk/src/build_tools/test.js
@@ -0,0 +1,6 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This is a dummy JavaScript file that will be loaded by browser_tester if no
+// example-specific test.js is found.
diff --git a/native_client_sdk/src/build_tools/test_projects.py b/native_client_sdk/src/build_tools/test_projects.py
index 517ab5a..5f82f12 100755
--- a/native_client_sdk/src/build_tools/test_projects.py
+++ b/native_client_sdk/src/build_tools/test_projects.py
@@ -13,7 +13,7 @@ import buildbot_common
import build_version
import parse_dsc
-from build_paths import OUT_DIR, SRC_DIR, SDK_SRC_DIR
+from build_paths import OUT_DIR, SRC_DIR, SDK_SRC_DIR, SCRIPT_DIR
sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
import getos
@@ -61,9 +61,6 @@ DISABLED_TESTS = [
{'name': 'graphics_3d', 'platform': ('win', 'linux')},
]
-DEFAULT_RETRY_ON_FAILURE_TIMES = 3
-
-
def ValidateToolchains(toolchains):
invalid_toolchains = set(toolchains) - set(ALL_TOOLCHAINS)
if invalid_toolchains:
@@ -77,6 +74,12 @@ def GetServingDirForProject(desc):
return os.path.join(path, desc['NAME'])
+def GetRepoServingDirForProject(desc):
+ # This differs from GetServingDirForProject, because it returns the location
+ # within the Chrome repository of the project, not the "pepperdir".
+ return os.path.dirname(desc['FILEPATH'])
+
+
def GetExecutableDirForProject(desc, toolchain, config):
return os.path.join(GetServingDirForProject(desc), toolchain, config)
@@ -92,9 +95,13 @@ def GetBrowserTesterCommand(desc, toolchain, config):
]
args.extend(['--serving_dir', GetServingDirForProject(desc)])
- exe_dir = GetExecutableDirForProject(desc, toolchain, config)
+ # Fall back on the example directory in the Chromium repo, to find test.js.
+ args.extend(['--serving_dir', GetRepoServingDirForProject(desc)])
+ # If it is not found there, fall back on the dummy one (in this directory.)
+ args.extend(['--serving_dir', SCRIPT_DIR])
if toolchain == platform:
+ exe_dir = GetExecutableDirForProject(desc, toolchain, config)
ppapi_plugin = os.path.join(exe_dir, desc['NAME'])
if platform == 'win':
ppapi_plugin += '.dll'
@@ -267,7 +274,7 @@ def GetProjectTree(include):
def main(args):
parser = optparse.OptionParser()
- parser.add_option('--config',
+ parser.add_option('-c', '--config',
help='Choose configuration to run (Debug or Release). Runs both '
'by default', action='append')
parser.add_option('-x', '--experimental',
@@ -283,7 +290,7 @@ def main(args):
action='append')
parser.add_option('--retry-times',
help='Number of types to retry on failure (Default: %default)',
- type='int', default=DEFAULT_RETRY_ON_FAILURE_TIMES)
+ type='int', default=1)
options, args = parser.parse_args(args[1:])
if args:
diff --git a/native_client_sdk/src/build_tools/test_sdk.py b/native_client_sdk/src/build_tools/test_sdk.py
index 6e7360b..bd5a00b 100755
--- a/native_client_sdk/src/build_tools/test_sdk.py
+++ b/native_client_sdk/src/build_tools/test_sdk.py
@@ -101,6 +101,7 @@ def StepRunBrowserTests(toolchains, experimental):
args = [
sys.executable,
os.path.join(SCRIPT_DIR, 'test_projects.py'),
+ '--retry-times=3',
]
if experimental:
diff --git a/native_client_sdk/src/examples/common.js b/native_client_sdk/src/examples/common.js
index 51adb54..79687d5 100644
--- a/native_client_sdk/src/examples/common.js
+++ b/native_client_sdk/src/examples/common.js
@@ -64,6 +64,56 @@ var common = (function() {
}
/**
+ * Inject a script into the DOM, and call a callback when it is loaded.
+ *
+ * @param {string} url The url of the script to load.
+ * @param {Function} onload The callback to call when the script is loaded.
+ * @param {Function} onerror The callback to call if the script fails to load.
+ */
+ function injectScript(url, onload, onerror) {
+ var scriptEl = document.createElement('script');
+ scriptEl.type = 'text/javascript';
+ scriptEl.src = url;
+ scriptEl.onload = onload;
+ if (onerror) {
+ scriptEl.addEventListener('error', onerror, false);
+ }
+ document.head.appendChild(scriptEl);
+ }
+
+ /**
+ * Run all tests for this example.
+ *
+ * @param {bool} waitForModule True if the tests should wait for the module
+ * to load. This is not necessary for trusted plugins (i.e. host plugins).
+ * @param {Object} moduleEl The module DOM element.
+ */
+ function runTests(waitForModule, moduleEl) {
+ console.log('runTests()');
+ common.tester = new Tester();
+
+ // All NaCl SDK examples are OK if the example exits cleanly; (i.e. the
+ // NaCl module returns 0 or calls exit(0)).
+ //
+ // Without this exception, the browser_tester thinks that the module
+ // has crashed.
+ common.tester.exitCleanlyIsOK();
+
+ common.tester.addAsyncTest('loaded', function(test) {
+ test.pass();
+ });
+
+ if (typeof window.addTests !== 'undefined') {
+ window.addTests();
+ }
+
+ if (waitForModule) {
+ common.tester.waitFor(moduleEl);
+ }
+ common.tester.run();
+ }
+
+ /**
* Create the Native Client <embed> element as a child of the DOM element
* named "listener".
*
@@ -86,7 +136,7 @@ var common = (function() {
// Add any optional arguments
if (attrs) {
for (var key in attrs) {
- moduleEl.setAttribute(key, attrs[key])
+ moduleEl.setAttribute(key, attrs[key]);
}
}
@@ -113,34 +163,16 @@ var common = (function() {
// This is code that is only used to test the SDK.
if (isTest) {
- var scriptEl = document.createElement('script');
- scriptEl.type = 'text/javascript';
- scriptEl.src = 'nacltest.js';
- document.head.appendChild(scriptEl);
-
- scriptEl.onload = function() {
- common.tester = new Tester();
-
- // All NaCl SDK examples are OK if the example exits cleanly; (i.e. the
- // NaCl module returns 0 or calls exit(0)).
- //
- // Without this exception, the browser_tester thinks that the module
- // has crashed.
- common.tester.exitCleanlyIsOK();
-
- common.tester.addAsyncTest('loaded', function(test) {
- test.pass();
+ var loadNaClTest = function() {
+ injectScript('nacltest.js', function() {
+ var waitForModule = !isHost;
+ runTests(waitForModule, moduleEl);
});
-
- if (typeof window.addTests !== 'undefined') {
- window.addTests();
- }
-
- if (!isHost) {
- common.tester.waitFor(moduleEl);
- }
- common.tester.run();
};
+
+ // Try to load test.js for the example. Whether or not it exists, load
+ // nacltest.js.
+ injectScript('test.js', loadNaClTest, loadNaClTest);
}
}
@@ -171,9 +203,9 @@ var common = (function() {
*/
function handleCrash(event) {
if (common.naclModule.exitStatus == -1) {
- updateStatus('CRASHED')
+ updateStatus('CRASHED');
} else {
- updateStatus('EXITED [' + common.naclModule.exitStatus + ']')
+ updateStatus('EXITED [' + common.naclModule.exitStatus + ']');
}
if (typeof window.handleCrash !== 'undefined') {
window.handleCrash(common.naclModule.lastError);
@@ -276,7 +308,7 @@ var common = (function() {
return;
}
- logMessage('Unhandled message: ' + message_event.data)
+ logMessage('Unhandled message: ' + message_event.data);
}
/**
diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
index 9fe640b..dbe0e4f 100644
--- a/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
+++ b/native_client_sdk/src/libraries/nacl_io/mount_node_html5fs.cc
@@ -122,22 +122,21 @@ Error MountNodeHtml5Fs::GetDents(size_t offs,
const char* file_name = mount_->ppapi()->GetVarInterface()
->VarToUtf8(file_name_var, &file_name_length);
- mount_->ppapi()->GetVarInterface()->Release(file_name_var);
-
- if (!file_name)
- continue;
+ if (file_name) {
+ file_name_length = std::min(
+ static_cast<size_t>(file_name_length),
+ sizeof(static_cast<struct dirent*>(0)->d_name) - 1); // -1 for NULL.
+
+ dirents.push_back(dirent());
+ struct dirent& direntry = dirents.back();
+ direntry.d_ino = 1; // Must be > 0.
+ direntry.d_off = sizeof(struct dirent);
+ direntry.d_reclen = sizeof(struct dirent);
+ strncpy(direntry.d_name, file_name, file_name_length);
+ direntry.d_name[file_name_length] = 0;
+ }
- file_name_length = std::min(
- static_cast<size_t>(file_name_length),
- sizeof(static_cast<struct dirent*>(0)->d_name) - 1); // -1 for NULL.
-
- dirents.push_back(dirent());
- struct dirent& direntry = dirents.back();
- direntry.d_ino = 1; // Must be > 0.
- direntry.d_off = sizeof(struct dirent);
- direntry.d_reclen = sizeof(struct dirent);
- strncpy(direntry.d_name, file_name, file_name_length);
- direntry.d_name[file_name_length] = 0;
+ mount_->ppapi()->GetVarInterface()->Release(file_name_var);
}
// Release the output buffer.
diff --git a/native_client_sdk/src/libraries/nacl_io_test/example.js b/native_client_sdk/src/libraries/nacl_io_test/example.js
index bd17594..3a65c89 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/example.js
+++ b/native_client_sdk/src/libraries/nacl_io_test/example.js
@@ -9,6 +9,8 @@ function moduleDidLoad() {
}
var currentTestEl = null;
+var failedTests = 0;
+var testsFinished = false;
function startCommand(testName) {
var testListEl = document.getElementById('tests');
@@ -32,6 +34,7 @@ function failCommand(fileName, lineNumber, summary) {
var testMessageEl = document.createElement('pre');
testMessageEl.textContent += fileName + ':' + lineNumber + ': ' + summary;
currentTestEl.appendChild(testMessageEl);
+ failedTests++;
}
function endCommand(testName, testResult) {
@@ -41,10 +44,14 @@ function endCommand(testName, testResult) {
testResultEl.textContent = testResult;
}
+function testendCommand() {
+ testsFinished = true;
+}
+
function handleMessage(event) {
var msg = event.data;
var firstColon = msg.indexOf(':');
- var cmd = msg.substr(0, firstColon);
+ var cmd = firstColon !== -1 ? msg.substr(0, firstColon) : msg;
var cmdFunctionName = cmd + 'Command';
var cmdFunction = window[cmdFunctionName];
diff --git a/native_client_sdk/src/libraries/nacl_io_test/main.cc b/native_client_sdk/src/libraries/nacl_io_test/main.cc
index ef7b094..9df6d4b 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/main.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/main.cc
@@ -50,6 +50,10 @@ class GTestEventListener : public ::testing::EmptyTestEventListener {
<< "," << (test_info.result()->Failed() ? "failed" : "ok");
pp::Instance(PSGetInstanceId()).PostMessage(msg.str());
}
+
+ virtual void OnTestProgramEnd(const ::testing::UnitTest&) {
+ pp::Instance(PSGetInstanceId()).PostMessage("testend");
+ }
};
int example_main(int argc, char* argv[]) {
diff --git a/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc b/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
index 514bb05..25331d8 100644
--- a/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
+++ b/native_client_sdk/src/libraries/nacl_io_test/mount_html5fs_test.cc
@@ -603,13 +603,18 @@ TEST_F(MountHtml5FsNodeSyncDirTest, GetDents) {
.WillOnce(Return(fileref_name_2));
EXPECT_CALL(*var, VarToUtf8(IsEqualToVar(fileref_name_1), _))
- .WillOnce(Return(fileref_name_cstr_1));
+ .WillOnce(DoAll(SetArgPointee<1>(strlen(fileref_name_cstr_1)),
+ Return(fileref_name_cstr_1)));
EXPECT_CALL(*var, VarToUtf8(IsEqualToVar(fileref_name_2), _))
- .WillOnce(Return(fileref_name_cstr_2));
+ .WillOnce(DoAll(SetArgPointee<1>(strlen(fileref_name_cstr_2)),
+ Return(fileref_name_cstr_2)));
+ EXPECT_CALL(*var, Release(IsEqualToVar(fileref_name_1)));
+ EXPECT_CALL(*var, Release(IsEqualToVar(fileref_name_2)));
EXPECT_CALL(*core_, ReleaseResource(fileref_resource_1));
EXPECT_CALL(*core_, ReleaseResource(fileref_resource_2));
+
struct dirent dirents[2];
memset(&dirents[0], 0, sizeof(dirents));
// +2 to test a size that is not a multiple of sizeof(dirent).
diff --git a/native_client_sdk/src/libraries/nacl_io_test/test.js b/native_client_sdk/src/libraries/nacl_io_test/test.js
new file mode 100644
index 0000000..d0c376c
--- /dev/null
+++ b/native_client_sdk/src/libraries/nacl_io_test/test.js
@@ -0,0 +1,18 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+function addTests() {
+ common.tester.addAsyncTest('nacl_io_test', function (test) {
+ var intervalId = window.setInterval(function () {
+ if (!testsFinished)
+ return;
+
+ window.clearInterval(intervalId);
+ if (failedTests > 0)
+ test.fail('tests failed');
+ else
+ test.pass();
+ }, 100);
+ });
+}