diff options
-rw-r--r-- | base/base.xcodeproj/project.pbxproj | 10 | ||||
-rw-r--r-- | base/base_unittest_exported_symbols.version | 5 | ||||
-rw-r--r-- | base/base_unittests.scons | 9 | ||||
-rw-r--r-- | base/multiprocess_test.h | 18 | ||||
-rw-r--r-- | base/port.h | 7 | ||||
-rw-r--r-- | base/process_util_unittest.cc | 4 | ||||
-rw-r--r-- | base/stats_table_unittest.cc | 3 | ||||
-rw-r--r-- | base/test_suite.h | 26 | ||||
-rw-r--r-- | testing/SConscript.gtest | 1 | ||||
-rw-r--r-- | testing/gtest.vcproj | 4 | ||||
-rw-r--r-- | testing/gtest.xcodeproj/project.pbxproj | 6 | ||||
-rw-r--r-- | testing/multiprocess_func_list.cc | 43 | ||||
-rw-r--r-- | testing/multiprocess_func_list.h | 57 |
13 files changed, 134 insertions, 59 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj index ba9e8a4..1c438c3 100644 --- a/base/base.xcodeproj/project.pbxproj +++ b/base/base.xcodeproj/project.pbxproj @@ -171,6 +171,9 @@ B57E4D780E9C26340090055D /* idletimer_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B57E4D770E9C26340090055D /* idletimer_unittest.cc */; }; B5D544AB0EAFB7E000272A1C /* sys_string_conversions_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5D544AA0EAFB7E000272A1C /* sys_string_conversions_unittest.cc */; }; B5EF235C0E89ABF500E1E114 /* platform_canvas_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = ABE1BA0C0E756EC4009041DA /* platform_canvas_unittest.cc */; }; + B5F7AFD20EB77ACA00EDB165 /* stats_table_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = B5F7AFD10EB77ACA00EDB165 /* stats_table_unittest.cc */; }; + B5F7AFD80EB77B1600EDB165 /* process_util_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = B5F7AFD70EB77B1600EDB165 /* process_util_mac.mm */; }; + B5F7B1F30EB7B3DA00EDB165 /* process_util_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BD8F4A00E65AA2400034DE9 /* process_util_unittest.cc */; }; BA0F69870E79D7980079A8A1 /* thread_local_storage_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA0F69860E79D7980079A8A1 /* thread_local_storage_unittest.cc */; }; BA5CC5840E788093004EDD45 /* shared_memory_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA5CC5830E788093004EDD45 /* shared_memory_unittest.cc */; }; BA739A020E5E3242009842A7 /* tracked_objects_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = BA739A000E5E3242009842A7 /* tracked_objects_unittest.cc */; }; @@ -627,6 +630,8 @@ B52C916B0E9428F500208D01 /* clipboard_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = clipboard_unittest.cc; sourceTree = "<group>"; }; B57E4D770E9C26340090055D /* idletimer_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = idletimer_unittest.cc; sourceTree = "<group>"; }; B5D544AA0EAFB7E000272A1C /* sys_string_conversions_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sys_string_conversions_unittest.cc; sourceTree = "<group>"; }; + B5F7AFD10EB77ACA00EDB165 /* stats_table_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = stats_table_unittest.cc; sourceTree = "<group>"; }; + B5F7AFD70EB77B1600EDB165 /* process_util_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = process_util_mac.mm; sourceTree = "<group>"; }; BA0F69860E79D7980079A8A1 /* thread_local_storage_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = thread_local_storage_unittest.cc; sourceTree = "<group>"; }; BA5CC5830E788093004EDD45 /* shared_memory_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shared_memory_unittest.cc; sourceTree = "<group>"; }; BA739A000E5E3242009842A7 /* tracked_objects_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tracked_objects_unittest.cc; sourceTree = "<group>"; }; @@ -940,6 +945,7 @@ 820EB4F10E3A6127009668FC /* process.cc */, 820EB4F20E3A6127009668FC /* process.h */, 825403510D92D24D0006B936 /* process_util.h */, + B5F7AFD70EB77B1600EDB165 /* process_util_mac.mm */, 7BD8F49F0E65AA2400034DE9 /* process_util_posix.cc */, 7BD8F4A00E65AA2400034DE9 /* process_util_unittest.cc */, 8254034B0D92D23C0006B936 /* prtime.cc */, @@ -988,6 +994,7 @@ 825403780D92D2CF0006B936 /* stats_counters.h */, 825403790D92D2CF0006B936 /* stats_table.cc */, 8254037A0D92D2CF0006B936 /* stats_table.h */, + B5F7AFD10EB77ACA00EDB165 /* stats_table_unittest.cc */, 7BD8F7730E65E89800034DE9 /* string16.cc */, 821B91680DAABD7F00F350D7 /* string16.h */, E4A133420E37A3C400110AA2 /* string_escape.cc */, @@ -1383,6 +1390,7 @@ 824654A60DC25CD7007C2BAA /* pickle.cc in Sources */, 7BF164F30E660CA500AA999E /* platform_thread_mac.mm in Sources */, 93E703170E5D63E00046259B /* platform_thread_posix.cc in Sources */, + B5F7AFD80EB77B1600EDB165 /* process_util_mac.mm in Sources */, 7BD8F4A10E65AA4600034DE9 /* process_util_posix.cc in Sources */, 824654DF0DC26521007C2BAA /* prtime.cc in Sources */, 4D11B59A0E91730200EF7617 /* rand_util.cc in Sources */, @@ -1466,6 +1474,7 @@ 7B78D3970E54FE0100609465 /* pickle_unittest.cc in Sources */, B5EF235C0E89ABF500E1E114 /* platform_canvas_unittest.cc in Sources */, A5CB82980E5C74E300FD6825 /* platform_test_mac.mm in Sources */, + B5F7B1F30EB7B3DA00EDB165 /* process_util_unittest.cc in Sources */, 7B8505D50E5B441000730B43 /* png_codec_unittest.cc in Sources */, 7B78D3980E54FE0100609465 /* pr_time_unittest.cc in Sources */, 4D11B59C0E91730500EF7617 /* rand_util_unittest.cc in Sources */, @@ -1478,6 +1487,7 @@ 7BAE30E60E6D939F00C3F750 /* simple_thread_unittest.cc in Sources */, 7B78D39C0E54FE0100609465 /* singleton_unittest.cc in Sources */, 7B78D39D0E54FE0100609465 /* stack_container_unittest.cc in Sources */, + B5F7AFD20EB77ACA00EDB165 /* stats_table_unittest.cc in Sources */, 7B78D39E0E54FE0100609465 /* string_escape_unittest.cc in Sources */, 7B78D39F0E54FE0100609465 /* string_piece_unittest.cc in Sources */, 7B78D3A00E54FE0100609465 /* string_tokenizer_unittest.cc in Sources */, diff --git a/base/base_unittest_exported_symbols.version b/base/base_unittest_exported_symbols.version deleted file mode 100644 index 357ed6b..0000000 --- a/base/base_unittest_exported_symbols.version +++ /dev/null @@ -1,5 +0,0 @@ -# list of functions exported from the Linux base_unittests executable. -{ - SimpleChildProcess; - StatsTableMultipleProcessMain; -}; diff --git a/base/base_unittests.scons b/base/base_unittests.scons index 285f195..d247eef 100644 --- a/base/base_unittests.scons +++ b/base/base_unittests.scons @@ -60,19 +60,10 @@ if env['PLATFORM'] == 'win32': ) if env['PLATFORM'] == 'posix': - # Explicity list the functions we want to export from the base_unittest - # executable in the following file. - env['EXPORTED_SYMBOLS_FILE'] = \ - env.File('$CHROME_SRC_DIR/base/base_unittest_exported_symbols.version') - env.Append( LIBS = [ 'event', ], - LINKFLAGS = [ - '-Xlinker', - '--dynamic-list=$EXPORTED_SYMBOLS_FILE' - ], ) # These test files work on *all* platforms; tests that don't work diff --git a/base/multiprocess_test.h b/base/multiprocess_test.h index fb02107..69aa50b 100644 --- a/base/multiprocess_test.h +++ b/base/multiprocess_test.h @@ -10,6 +10,7 @@ #include "base/process_util.h" #include "base/string_util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "testing/multiprocess_func_list.h" #if defined(OS_POSIX) #include <sys/types.h> @@ -26,21 +27,15 @@ static const wchar_t kRunClientProcess[] = L"client"; // To create a multiprocess test simply follow these steps: // // 1) Derive your test from MultiProcessTest. -// 2) Modify your mainline so that if it sees the -// kRunClientProcess switch, it will deal with it. -// 3) Create a mainline function for the child processes -// 4) Call SpawnChild("foo"), where "foo" is the name of +// 2) Create a mainline function for the child processes and include +// testing/multiprocess_func_list.h. +// See the declaration of the MULTIPROCESS_TEST_MAIN macro +// in that file for an example. +// 3) Call SpawnChild("foo"), where "foo" is the name of // the function you wish to run in the child processes. -// 5) On Linux, add the function's name to the list in the file -// base_unittests_exported_symbols.version // That's it! // class MultiProcessTest : public PlatformTest { - public: - // Prototype function for a client function. Multi-process - // clients must provide a callback with this signature to run. - typedef int (*ChildFunctionPtr)(); - protected: // Run a child process. // 'procname' is the name of a function which the child will @@ -79,4 +74,3 @@ class MultiProcessTest : public PlatformTest { }; #endif // BASE_MULTIPROCESS_TEST_H__ - diff --git a/base/port.h b/base/port.h index 349b117..0e873bb 100644 --- a/base/port.h +++ b/base/port.h @@ -53,12 +53,7 @@ inline void va_copy(va_list& a, va_list& b) { // Define an OS-neutral wrapper for shared library entry points #if defined(OS_WIN) #define API_CALL __stdcall -#define DYNAMIC_EXPORT __declspec(dllexport) -#elif defined(OS_MACOSX) -#define DYNAMIC_EXPORT __attribute__((visibility("default"))) -#define API_CALL -#elif defined(OS_LINUX) -#define DYNAMIC_EXPORT +#elif defined(OS_LINUX) || defined(OS_MACOSX) #define API_CALL #endif diff --git a/base/process_util_unittest.cc b/base/process_util_unittest.cc index 32595c9..261eb46 100644 --- a/base/process_util_unittest.cc +++ b/base/process_util_unittest.cc @@ -17,9 +17,8 @@ namespace { class ProcessUtilTest : public MultiProcessTest { }; -} -extern "C" int DYNAMIC_EXPORT SimpleChildProcess() { +MULTIPROCESS_TEST_MAIN(SimpleChildProcess) { return 0; } @@ -99,3 +98,4 @@ TEST_F(ProcessUtilTest, CalcFreeMemory) { } #endif // defined(OS_WIN) +} // namespace diff --git a/base/stats_table_unittest.cc b/base/stats_table_unittest.cc index 3214cb5..aa7b2cb 100644 --- a/base/stats_table_unittest.cc +++ b/base/stats_table_unittest.cc @@ -8,6 +8,7 @@ #include "base/stats_counters.h" #include "base/string_util.h" #include "testing/gtest/include/gtest/gtest.h" +#include "testing/multiprocess_func_list.h" #if defined(OS_WIN) #include <process.h> @@ -151,7 +152,7 @@ TEST_F(StatsTableTest, MultipleThreads) { const std::wstring kTableName = L"MultipleProcessStatTable"; -extern "C" int DYNAMIC_EXPORT StatsTableMultipleProcessMain() { +MULTIPROCESS_TEST_MAIN(StatsTableMultipleProcessMain) { // Each process will open the shared memory and set counters // concurrently in a loop. We'll use some pauses to // mixup the scheduling. diff --git a/base/test_suite.h b/base/test_suite.h index 503aeda..1c0a785 100644 --- a/base/test_suite.h +++ b/base/test_suite.h @@ -16,15 +16,12 @@ #include "base/logging.h" #include "base/multiprocess_test.h" #include "testing/gtest/include/gtest/gtest.h" +#include "testing/multiprocess_func_list.h" #if defined(OS_WIN) #include <windows.h> -#include "base/multiprocess_test.h" #elif defined(OS_LINUX) -#include <dlfcn.h> #include <gtk/gtk.h> -#elif defined(OS_MACOSX) -#include <dlfcn.h> #endif class TestSuite { @@ -47,26 +44,7 @@ class TestSuite { // Convert our function name to a usable string for GetProcAddress. std::string func_name(client_func.begin(), client_func.end()); -#if defined(OS_WIN) - // Get our module handle and search for an exported function - // which we can use as our client main. - MultiProcessTest::ChildFunctionPtr func = - reinterpret_cast<MultiProcessTest::ChildFunctionPtr>( - GetProcAddress(GetModuleHandle(NULL), func_name.c_str())); -#elif defined(OS_LINUX) - void* exobj = dlopen(0, RTLD_LAZY); - MultiProcessTest::ChildFunctionPtr func = - reinterpret_cast<MultiProcessTest::ChildFunctionPtr>( - dlsym(exobj, func_name.c_str())); -#elif defined(OS_MACOSX) - MultiProcessTest::ChildFunctionPtr func = - reinterpret_cast<MultiProcessTest::ChildFunctionPtr>( - dlsym(RTLD_SELF, func_name.c_str())); -#endif // defined(OS_MACOSX) - - if (func) - return (*func)(); - return -1; + return multi_process_function_list::InvokeChildProcessTest(func_name); } int result = RUN_ALL_TESTS(); diff --git a/testing/SConscript.gtest b/testing/SConscript.gtest index 4f6bbf0..bc5456a 100644 --- a/testing/SConscript.gtest +++ b/testing/SConscript.gtest @@ -28,6 +28,7 @@ input_files = [ 'gtest/src/gtest-filepath.cc', 'gtest/src/gtest-port.cc', 'gtest/src/gtest.cc', + 'multiprocess_func_list.cc', ] env.ChromeStaticLibrary('gtest', input_files) diff --git a/testing/gtest.vcproj b/testing/gtest.vcproj index 02a9834..62421c4 100644 --- a/testing/gtest.vcproj +++ b/testing/gtest.vcproj @@ -184,6 +184,10 @@ RelativePath="gtest\include\gtest\gtest_prod.h" > </File> + <File + RelativePath="multiprocess_func_list.cc" + > + </File> </Files> <Globals> </Globals> diff --git a/testing/gtest.xcodeproj/project.pbxproj b/testing/gtest.xcodeproj/project.pbxproj index c733d65..9498879 100644 --- a/testing/gtest.xcodeproj/project.pbxproj +++ b/testing/gtest.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + B593AFF90EB7D41B00B72887 /* multiprocess_func_list.cc in Sources */ = {isa = PBXBuildFile; fileRef = B593AFF70EB7D41B00B72887 /* multiprocess_func_list.cc */; }; E45A2BBC0E47A20200DB1196 /* gtest_main.cc in Sources */ = {isa = PBXBuildFile; fileRef = E45A2BB60E47A20200DB1196 /* gtest_main.cc */; }; E45A2BBD0E47A20200DB1196 /* gtest-death-test.cc in Sources */ = {isa = PBXBuildFile; fileRef = E45A2BB70E47A20200DB1196 /* gtest-death-test.cc */; }; E45A2BBE0E47A20200DB1196 /* gtest-filepath.cc in Sources */ = {isa = PBXBuildFile; fileRef = E45A2BB80E47A20200DB1196 /* gtest-filepath.cc */; }; @@ -20,6 +21,8 @@ 7B836C760E55C8CC00F6AD31 /* release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = release.xcconfig; sourceTree = "<group>"; }; 7BED30DF0E59F69A00A747DB /* executable.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = executable.xcconfig; sourceTree = "<group>"; }; 7BED30E00E59F69A00A747DB /* staticlib.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = staticlib.xcconfig; sourceTree = "<group>"; }; + B593AFF70EB7D41B00B72887 /* multiprocess_func_list.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = multiprocess_func_list.cc; sourceTree = SOURCE_ROOT; }; + B593AFF80EB7D41B00B72887 /* multiprocess_func_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = multiprocess_func_list.h; sourceTree = SOURCE_ROOT; }; D2AAC046055464E500DB518D /* libgtest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libgtest.a; sourceTree = BUILT_PRODUCTS_DIR; }; E45A2BB60E47A20200DB1196 /* gtest_main.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = gtest_main.cc; sourceTree = "<group>"; }; E45A2BB70E47A20200DB1196 /* gtest-death-test.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = "gtest-death-test.cc"; sourceTree = "<group>"; }; @@ -59,6 +62,8 @@ E45A2BBA0E47A20200DB1196 /* gtest-port.cc */, E45A2BBB0E47A20200DB1196 /* gtest.cc */, E45A2BB60E47A20200DB1196 /* gtest_main.cc */, + B593AFF70EB7D41B00B72887 /* multiprocess_func_list.cc */, + B593AFF80EB7D41B00B72887 /* multiprocess_func_list.h */, ); name = Source; path = gtest/src; @@ -131,6 +136,7 @@ E45A2BC00E47A20200DB1196 /* gtest-port.cc in Sources */, E45A2BC10E47A20200DB1196 /* gtest.cc in Sources */, E45A2BBC0E47A20200DB1196 /* gtest_main.cc in Sources */, + B593AFF90EB7D41B00B72887 /* multiprocess_func_list.cc in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/testing/multiprocess_func_list.cc b/testing/multiprocess_func_list.cc new file mode 100644 index 0000000..236edbf --- /dev/null +++ b/testing/multiprocess_func_list.cc @@ -0,0 +1,43 @@ +// Copyright (c) 2008 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 "multiprocess_func_list.h" + +#include <map> + +// Helper functions to maintain mapping of "test name"->test func. +// The information is accessed via a global map. +namespace multi_process_function_list { + +namespace { + +typedef std::map<std::string, ChildFunctionPtr> MultiProcessTestMap; + +// Retrieve a reference to the global 'func name' -> func ptr map. +MultiProcessTestMap &GetMultiprocessFuncMap() { + static MultiProcessTestMap test_name_to_func_ptr_map; + return test_name_to_func_ptr_map; +} + +} // namespace + +AppendMultiProcessTest::AppendMultiProcessTest(std::string test_name, + ChildFunctionPtr func_ptr) { + GetMultiprocessFuncMap()[test_name] = func_ptr; +} + +int InvokeChildProcessTest(std::string test_name) { + MultiProcessTestMap &func_lookup_table = GetMultiprocessFuncMap(); + MultiProcessTestMap::iterator it = func_lookup_table.find(test_name); + if (it != func_lookup_table.end()) { + ChildFunctionPtr func = it->second; + if (func) { + return (*func)(); + } + } + + return -1; +} + +} // namespace multi_process_function_list diff --git a/testing/multiprocess_func_list.h b/testing/multiprocess_func_list.h new file mode 100644 index 0000000..0d53b2b --- /dev/null +++ b/testing/multiprocess_func_list.h @@ -0,0 +1,57 @@ +// Copyright (c) 2008 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. + +#ifndef TESTING_MULTIPROCESS_FUNC_LIST_H_ +#define TESTING_MULTIPROCESS_FUNC_LIST_H_ + +#include <string> + +// This file provides the plumbing to register functions to be executed +// as the main function of a child process in a multi-process test. +// This complements the MultiProcessTest class which provides facilities +// for launching such tests. +// +// The MULTIPROCESS_TEST_MAIN() macro registers a string -> func_ptr mapping +// by creating a new global instance of the AppendMultiProcessTest() class +// this means that by the time that we reach our main() function the mapping +// is already in place. +// +// Example usage: +// MULTIPROCESS_TEST_MAIN(a_test_func) { +// // Code here runs in a child process. +// return 0; +// } +// +// The prototype of a_test_func is implicitly +// int test_main_func_name(); + +namespace multi_process_function_list { + +// Type for child process main functions. +typedef int (*ChildFunctionPtr)(); + +// Helper class to append a test function to the global mapping. +// Used by the MULTIPROCESS_TEST_MAIN macro. +class AppendMultiProcessTest { + public: + AppendMultiProcessTest(std::string test_name, ChildFunctionPtr func_ptr); +}; + +// Invoke the main function of a test previously registered with +// MULTIPROCESS_TEST_MAIN() +int InvokeChildProcessTest(std::string test_name); + +// This macro creates a global MultiProcessTest::AppendMultiProcessTest object +// whose constructor does the work of adding the global mapping. +#define MULTIPROCESS_TEST_MAIN(test_main) \ + int test_main(); \ + namespace { \ + multi_process_function_list::AppendMultiProcessTest \ + AddMultiProcessTest##_##test_main(#test_main, (test_main)); \ + } \ + int test_main() + +} // namespace multi_process_function_list + +#endif // TESTING_MULTIPROCESS_FUNC_LIST_H_ |