Commit 08e64697 authored by ncbray@google.com's avatar ncbray@google.com

Add NaCl smoke test to browser_tests.

The smoke test is simple - it checks that Chrome can load nexes. The more
interesting part of this CL is that it lays the groundwork for adding more NaCl
tests to browser_tests. This will allow many nacl_integration tests to be
rewritten as browser_tests. This CL adds an extensible jig for decoding
messages from Javascript, which makes it easier to add test logic in the web
page. This CL also establishes locations in the build directory for nexes and
other test data.

There are two followup CLs planned: 1) simplify how nexes are built in GYP
and 2) share the code for running tests in Javascript with the PPAPI test
suite.

This is a recommit of r151716 with Linux ASAN tests disabled and GYP tweaks for
VS2010.

BUG= http://code.google.com/p/nativeclient/issues/detail?id=2959
TEST= browser_tests --gtest_filter=NaClBrowserTest*

Review URL: https://chromiumcodereview.appspot.com/10827357

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@151963 0039d316-1c4b-4281-b951-d872f2087c98
parent d3128595
...@@ -3100,8 +3100,12 @@ ...@@ -3100,8 +3100,12 @@
], ],
'conditions': [ 'conditions': [
['disable_nacl_untrusted==0', { ['disable_nacl_untrusted==0', {
'sources': [
'test/nacl/nacl_browsertest.cc',
],
'dependencies': [ 'dependencies': [
'../ppapi/ppapi_untrusted.gyp:ppapi_nacl_tests', 'test/data/nacl/nacl_test_data.gyp:nacl_tests',
'../ppapi/ppapi_untrusted.gyp:ppapi_nacl_tests',
], ],
}], }],
['OS=="win" or OS=="linux"', { ['OS=="win" or OS=="linux"', {
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "base/callback.h" #include "base/callback.h"
#include "base/command_line.h" #include "base/command_line.h"
#include "base/file_path.h" #include "base/file_path.h"
#include "base/file_util.h"
#include "base/json/json_reader.h" #include "base/json/json_reader.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/message_loop.h" #include "base/message_loop.h"
...@@ -315,6 +316,48 @@ GURL GetTestUrl(const FilePath& dir, const FilePath& file) { ...@@ -315,6 +316,48 @@ GURL GetTestUrl(const FilePath& dir, const FilePath& file) {
return net::FilePathToFileURL(GetTestFilePath(dir, file)); return net::FilePathToFileURL(GetTestFilePath(dir, file));
} }
bool GetRelativeBuildDirectory(FilePath* build_dir) {
// This function is used to find the build directory so TestServer can serve
// built files (nexes, etc). TestServer expects a path relative to the source
// root.
FilePath exe_dir = CommandLine::ForCurrentProcess()->GetProgram().DirName();
FilePath src_dir;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
return false;
// We must first generate absolute paths to SRC and EXE and from there
// generate a relative path.
if (!exe_dir.IsAbsolute())
file_util::AbsolutePath(&exe_dir);
if (!src_dir.IsAbsolute())
file_util::AbsolutePath(&src_dir);
if (!exe_dir.IsAbsolute())
return false;
if (!src_dir.IsAbsolute())
return false;
size_t match, exe_size, src_size;
std::vector<FilePath::StringType> src_parts, exe_parts;
// Determine point at which src and exe diverge.
exe_dir.GetComponents(&exe_parts);
src_dir.GetComponents(&src_parts);
exe_size = exe_parts.size();
src_size = src_parts.size();
for (match = 0; match < exe_size && match < src_size; ++match) {
if (exe_parts[match] != src_parts[match])
break;
}
// Create a relative path.
*build_dir = FilePath();
for (size_t tmp_itr = match; tmp_itr < src_size; ++tmp_itr)
*build_dir = build_dir->Append(FILE_PATH_LITERAL(".."));
for (; match < exe_size; ++match)
*build_dir = build_dir->Append(exe_parts[match]);
return true;
}
AppModalDialog* WaitForAppModalDialog() { AppModalDialog* WaitForAppModalDialog() {
content::WindowedNotificationObserver observer( content::WindowedNotificationObserver observer(
chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN, chrome::NOTIFICATION_APP_MODAL_DIALOG_SHOWN,
......
...@@ -130,6 +130,9 @@ FilePath GetTestFilePath(const FilePath& dir, const FilePath& file); ...@@ -130,6 +130,9 @@ FilePath GetTestFilePath(const FilePath& dir, const FilePath& file);
// The returned path is GURL format. // The returned path is GURL format.
GURL GetTestUrl(const FilePath& dir, const FilePath& file); GURL GetTestUrl(const FilePath& dir, const FilePath& file);
// Generate the path of the build directory, relative to the source root.
bool GetRelativeBuildDirectory(FilePath *build_dir);
// Blocks until an application modal dialog is showns and returns it. // Blocks until an application modal dialog is showns and returns it.
AppModalDialog* WaitForAppModalDialog(); AppModalDialog* WaitForAppModalDialog();
......
include_rules = [
# NaCl modules include PPAPI headers.
"+ppapi",
]
set noparent
bradnelson@chromium.org
ncbray@chromium.org
mseaborn@chromium.org
<html>
<!--
Copyright (c) 2012 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.
-->
<head>
<title>NaCl Load Test</title>
</head>
<body>
<h2>NaCl Load Test</h2>
</body>
<script>
function report(msg) {
domAutomationController.setAutomationId(0);
// The automation controller seems to choke on Objects, so turn them into
// strings.
domAutomationController.send(JSON.stringify(msg));
}
function create(manifest_url) {
var embed = document.createElement("embed");
embed.src = manifest_url;
embed.type = "application/x-nacl";
embed.addEventListener("load", function(evt) {
report({type: "Shutdown", message: "1 test passed.", passed: true});
}, true);
embed.addEventListener("error", function(evt) {
report({type: "Log", message: "Load error: " + embed.lastError});
report({type: "Shutdown", message: "1 test failed.", passed: false});
}, true);
document.body.appendChild(embed);
}
create("simple.nmf");
</script>
</html>
# Copyright (c) 2012 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.
{
'includes': [
'../../../../native_client/build/untrusted.gypi',
],
# TODO(ncbray) factor nexe building code into a common file.
'targets': [
{
'target_name': 'nacl_tests',
'type': 'none',
'dependencies': [
'../../../../ppapi/ppapi_untrusted.gyp:ppapi_cpp_lib',
'../../../../ppapi/native_client/native_client.gyp:ppapi_lib',
'../../../../ppapi/native_client/native_client.gyp:nacl_irt',
],
'copies': [
{
'destination': '<(PRODUCT_DIR)/nacl_test_data/newlib',
'files': [
'nacl_load_test.html',
],
},
{
'destination': '<(PRODUCT_DIR)/nacl_test_data/glibc',
'files': [
'nacl_load_test.html',
],
},
],
'variables': {
'nexe_target': 'simple',
'build_newlib': 1,
'out_newlib32': '<(PRODUCT_DIR)/nacl_test_data/newlib/>(nexe_target)_newlib_x86_32.nexe',
'out_newlib64': '<(PRODUCT_DIR)/nacl_test_data/newlib/>(nexe_target)_newlib_x86_64.nexe',
'out_newlib_arm': '<(PRODUCT_DIR)/nacl_test_data/newlib/>(nexe_target)_newlib_arm.nexe',
'out_glibc32': '<(PRODUCT_DIR)/nacl_test_data/glibc/>(nexe_target)_glibc_x86_32.nexe',
'out_glibc64': '<(PRODUCT_DIR)/nacl_test_data/glibc/>(nexe_target)_glibc_x86_64.nexe',
'out_glibc_arm': '<(PRODUCT_DIR)/nacl_test_data/glibc/>(nexe_target)_glibc_arm.nexe',
'nmf_newlib%': '<(PRODUCT_DIR)/nacl_test_data/newlib/>(nexe_target).nmf',
'include_dirs': [
'../../../..',
],
'link_flags': [
'-lppapi_cpp',
'-lppapi',
'-lpthread',
],
'sources': [
'simple.cc',
],
},
'actions': [
{
'action_name': 'Generate NEWLIB NMF',
# Unlike glibc, nexes are not actually inputs - only the names matter.
# We don't have the nexes as inputs because the ARM nexe may not
# exist. However, VS 2010 seems to blackhole this entire target if
# there are no inputs to this action. To work around this we add a
# bogus input.
'inputs': ['nacl_test_data.gyp'],
'outputs': ['>(nmf_newlib)'],
'action': [
'python',
'<(DEPTH)/native_client_sdk/src/tools/create_nmf.py',
'>(out_newlib64)', '>(out_newlib32)', '>(out_newlib_arm)',
'--output=>(nmf_newlib)',
'--toolchain=newlib',
],
},
],
'conditions': [
['target_arch!="arm" and disable_glibc==0', {
'variables': {
'build_glibc': 1,
# NOTE: Use /lib, not /lib64 here; it is a symbolic link which
# doesn't work on Windows.
'libdir_glibc64': '>(nacl_glibc_tc_root)/x86_64-nacl/lib',
'libdir_glibc32': '>(nacl_glibc_tc_root)/x86_64-nacl/lib32',
'nacl_objdump': '>(nacl_glibc_tc_root)/bin/x86_64-nacl-objdump',
'nmf_glibc%': '<(PRODUCT_DIR)/nacl_test_data/glibc/>(nexe_target).nmf',
},
'actions': [
{
'action_name': 'Generate GLIBC NMF and copy libs',
'inputs': ['>(out_glibc64)', '>(out_glibc32)'],
# NOTE: There is no explicit dependency for the lib32
# and lib64 directories created in the PRODUCT_DIR.
# They are created as a side-effect of NMF creation.
'outputs': ['>(nmf_glibc)'],
'action': [
'python',
'<(DEPTH)/native_client_sdk/src/tools/create_nmf.py',
'>@(_inputs)',
'--objdump=>(nacl_objdump)',
'--library-path=>(libdir_glibc64)',
'--library-path=>(libdir_glibc32)',
'--output=>(nmf_glibc)',
'--stage-dependencies=<(PRODUCT_DIR)/nacl_test_data/glibc',
'--toolchain=glibc',
],
},
],
}],
],
},
],
}
// Copyright (c) 2012 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.
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
class SimpleInstance : public pp::Instance {
public:
explicit SimpleInstance(PP_Instance instance) : pp::Instance(instance) {
}
};
class SimpleModule : public pp::Module {
public:
virtual pp::Instance* CreateInstance(PP_Instance instance) {
return new SimpleInstance(instance);
}
};
namespace pp {
Module* CreateModule() {
return new SimpleModule();
}
} // namespace pp
bradnelson@chromium.org
ncbray@chromium.org
mseaborn@chromium.org
This diff is collapsed.
...@@ -166,13 +166,13 @@ void PPAPITestBase::RunTestAndReload(const std::string& test_case) { ...@@ -166,13 +166,13 @@ void PPAPITestBase::RunTestAndReload(const std::string& test_case) {
void PPAPITestBase::RunTestViaHTTP(const std::string& test_case) { void PPAPITestBase::RunTestViaHTTP(const std::string& test_case) {
FilePath document_root; FilePath document_root;
ASSERT_TRUE(GetHTTPDocumentRoot(&document_root)); ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
RunHTTPTestServer(document_root, test_case, ""); RunHTTPTestServer(document_root, test_case, "");
} }
void PPAPITestBase::RunTestWithSSLServer(const std::string& test_case) { void PPAPITestBase::RunTestWithSSLServer(const std::string& test_case) {
FilePath document_root; FilePath document_root;
ASSERT_TRUE(GetHTTPDocumentRoot(&document_root)); ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&document_root));
net::TestServer test_server(net::BaseTestServer::HTTPSOptions(), net::TestServer test_server(net::BaseTestServer::HTTPSOptions(),
document_root); document_root);
ASSERT_TRUE(test_server.Start()); ASSERT_TRUE(test_server.Start());
...@@ -189,7 +189,7 @@ void PPAPITestBase::RunTestWithWebSocketServer(const std::string& test_case) { ...@@ -189,7 +189,7 @@ void PPAPITestBase::RunTestWithWebSocketServer(const std::string& test_case) {
int port = server.UseRandomPort(); int port = server.UseRandomPort();
ASSERT_TRUE(server.Start(websocket_root_dir)); ASSERT_TRUE(server.Start(websocket_root_dir));
FilePath http_document_root; FilePath http_document_root;
ASSERT_TRUE(GetHTTPDocumentRoot(&http_document_root)); ASSERT_TRUE(ui_test_utils::GetRelativeBuildDirectory(&http_document_root));
RunHTTPTestServer(http_document_root, test_case, RunHTTPTestServer(http_document_root, test_case,
StringPrintf("websocket_port=%d", port)); StringPrintf("websocket_port=%d", port));
} }
...@@ -256,45 +256,6 @@ void PPAPITestBase::RunHTTPTestServer( ...@@ -256,45 +256,6 @@ void PPAPITestBase::RunHTTPTestServer(
RunTestURL(url); RunTestURL(url);
} }
bool PPAPITestBase::GetHTTPDocumentRoot(FilePath* document_root) {
// For HTTP tests, we use the output DIR to grab the generated files such
// as the NEXEs.
FilePath exe_dir = CommandLine::ForCurrentProcess()->GetProgram().DirName();
FilePath src_dir;
if (!PathService::Get(base::DIR_SOURCE_ROOT, &src_dir))
return false;
// TestServer expects a path relative to source. So we must first
// generate absolute paths to SRC and EXE and from there generate
// a relative path.
if (!exe_dir.IsAbsolute()) file_util::AbsolutePath(&exe_dir);
if (!src_dir.IsAbsolute()) file_util::AbsolutePath(&src_dir);
if (!exe_dir.IsAbsolute())
return false;
if (!src_dir.IsAbsolute())
return false;
size_t match, exe_size, src_size;
std::vector<FilePath::StringType> src_parts, exe_parts;
// Determine point at which src and exe diverge, and create a relative path.
exe_dir.GetComponents(&exe_parts);
src_dir.GetComponents(&src_parts);
exe_size = exe_parts.size();
src_size = src_parts.size();
for (match = 0; match < exe_size && match < src_size; ++match) {
if (exe_parts[match] != src_parts[match])
break;
}
for (size_t tmp_itr = match; tmp_itr < src_size; ++tmp_itr) {
*document_root = document_root->Append(FILE_PATH_LITERAL(".."));
}
for (; match < exe_size; ++match) {
*document_root = document_root->Append(exe_parts[match]);
}
return true;
}
PPAPITest::PPAPITest() { PPAPITest::PPAPITest() {
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment