diff options
author | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 17:12:27 +0000 |
---|---|---|
committer | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-08-16 17:12:27 +0000 |
commit | 20b417d88f0d3d4156c91278d9111e3a493886ec (patch) | |
tree | 93d2e147474d60c1df27e5de79dde082da32b0c6 /native_client_sdk | |
parent | 1078219ee033739693c6fee4225bb690b5aa3ab4 (diff) | |
download | chromium_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')
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); + }); +} |