diff options
author | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 08:52:03 +0000 |
---|---|---|
committer | jamesr@chromium.org <jamesr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-07 08:52:03 +0000 |
commit | 1b901a3348e02376b2cd95f52cf86cc0787c63c6 (patch) | |
tree | e1b3fed2484988ebf7a7302b5fe89792215f418f /cc | |
parent | 82a5c3c0c0bc28dd0fa1ff1a8dab7c6c383b3c49 (diff) | |
download | chromium_src-1b901a3348e02376b2cd95f52cf86cc0787c63c6.zip chromium_src-1b901a3348e02376b2cd95f52cf86cc0787c63c6.tar.gz chromium_src-1b901a3348e02376b2cd95f52cf86cc0787c63c6.tar.bz2 |
Basic pixel tests for cc
BUG=
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=171544
Review URL: https://chromiumcodereview.appspot.com/11412289
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@171735 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cc')
-rw-r--r-- | cc/DEPS | 1 | ||||
-rw-r--r-- | cc/cc_tests.gyp | 35 | ||||
-rw-r--r-- | cc/gl_renderer_pixeltest.cc | 116 | ||||
-rw-r--r-- | cc/layer_tree_host_perftest.cc | 11 | ||||
-rw-r--r-- | cc/test/DEPS | 5 | ||||
-rw-r--r-- | cc/test/cc_test_suite.cc | 31 | ||||
-rw-r--r-- | cc/test/cc_test_suite.h | 36 | ||||
-rw-r--r-- | cc/test/paths.cc | 44 | ||||
-rw-r--r-- | cc/test/paths.h | 26 | ||||
-rw-r--r-- | cc/test/pixel_test_output_surface.cc | 36 | ||||
-rw-r--r-- | cc/test/pixel_test_output_surface.h | 37 | ||||
-rw-r--r-- | cc/test/pixel_test_utils.cc | 81 | ||||
-rw-r--r-- | cc/test/pixel_test_utils.h | 25 | ||||
-rw-r--r-- | cc/test/run_all_unittests.cc | 4 |
14 files changed, 473 insertions, 15 deletions
@@ -5,6 +5,7 @@ include_rules = [ "+third_party/khronos/GLES2/gl2.h", "+third_party/khronos/GLES2/gl2ext.h", "+ui/gfx", + "+ui/gl", # TODO(danakj): Drop dependencies on WebKit Platform API from cc. "+third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h", "+third_party/WebKit/Source/Platform/chromium/public/WebGraphicsMemoryAllocation.h", diff --git a/cc/cc_tests.gyp b/cc/cc_tests.gyp index 7887aca..1ba44b5 100644 --- a/cc/cc_tests.gyp +++ b/cc/cc_tests.gyp @@ -16,6 +16,7 @@ 'float_quad_unittest.cc', 'frame_rate_controller_unittest.cc', 'gl_renderer_unittest.cc', + 'gl_renderer_pixeltest.cc', 'hash_pair_unittest.cc', 'heads_up_display_unittest.cc', 'keyframed_animation_curve_unittest.cc', @@ -86,6 +87,10 @@ 'test/mock_quad_culler.cc', 'test/mock_quad_culler.h', 'test/occlusion_tracker_test_common.h', + 'test/paths.cc', + 'test/paths.h', + 'test/pixel_test_output_surface.cc', + 'test/pixel_test_output_surface.h', 'test/render_pass_test_common.cc', 'test/render_pass_test_common.h', 'test/scheduler_test_common.cc', @@ -105,11 +110,14 @@ '../testing/gmock.gyp:gmock', '../testing/gtest.gyp:gtest', '../ui/ui.gyp:ui', + '../webkit/support/webkit_support.gyp:webkit_gpu', 'cc.gyp:cc', 'cc_test_support', + 'cc_test_utils', ], 'sources': [ 'test/run_all_unittests.cc', + 'test/cc_test_suite.cc', '<@(cc_unit_tests_source_files)', ], 'include_dirs': [ @@ -141,6 +149,7 @@ 'sources': [ 'layer_tree_host_perftest.cc', 'test/run_all_unittests.cc', + 'test/cc_test_suite.cc', ], 'include_dirs': [ 'test', @@ -165,16 +174,32 @@ '../third_party/WebKit/Source/Platform/chromium', ], 'dependencies': [ - '../ui/gl/gl.gyp:gl', - '../testing/gtest.gyp:gtest', - '../testing/gmock.gyp:gmock', '../skia/skia.gyp:skia', + '../testing/gmock.gyp:gmock', + '../testing/gtest.gyp:gtest', '../third_party/WebKit/Source/WebKit/chromium/WebKit.gyp:webkit', + '../third_party/mesa/mesa.gyp:osmesa', + '../ui/gl/gl.gyp:gl', ], 'sources': [ '<@(cc_tests_support_files)', ], }, + { + 'target_name': 'cc_test_utils', + 'type': 'static_library', + 'include_dirs': [ + '..' + ], + 'sources': [ + 'test/pixel_test_utils.cc', + 'test/pixel_test_utils.h', + ], + 'dependencies': [ + '../skia/skia.gyp:skia', + '../ui/ui.gyp:ui', # for png_codec + ], + }, ], 'conditions': [ # Special target to wrap a gtest_target_type==shared_library @@ -193,10 +218,6 @@ }, 'includes': [ '../build/apk_test.gypi' ], }, - ], - }], - ['OS == "android" and gtest_target_type == "shared_library"', { - 'targets': [ { 'target_name': 'cc_perftests_apk', 'type': 'none', diff --git a/cc/gl_renderer_pixeltest.cc b/cc/gl_renderer_pixeltest.cc new file mode 100644 index 0000000..feadf37 --- /dev/null +++ b/cc/gl_renderer_pixeltest.cc @@ -0,0 +1,116 @@ +// Copyright 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 "cc/gl_renderer.h" + +#include "base/file_util.h" +#include "base/path_service.h" +#include "cc/draw_quad.h" +#include "cc/prioritized_resource_manager.h" +#include "cc/resource_provider.h" +#include "cc/test/paths.h" +#include "cc/test/pixel_test_output_surface.h" +#include "cc/test/pixel_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gl/gl_implementation.h" + +namespace cc { +namespace { + +class FakeRendererClient : public RendererClient { + public: + FakeRendererClient() + { + } + + // RendererClient methods. + virtual const gfx::Size& deviceViewportSize() const OVERRIDE { + static gfx::Size fake_size(200, 200); + return fake_size; + } + virtual const LayerTreeSettings& settings() const OVERRIDE { + static LayerTreeSettings fake_settings; + return fake_settings; + } + virtual void didLoseOutputSurface() OVERRIDE { } + virtual void onSwapBuffersComplete() OVERRIDE { } + virtual void setFullRootLayerDamage() OVERRIDE { } + virtual void setManagedMemoryPolicy(const ManagedMemoryPolicy&) OVERRIDE {} + virtual void enforceManagedMemoryPolicy( + const ManagedMemoryPolicy&) OVERRIDE {} + virtual bool hasImplThread() const OVERRIDE { return false; } +}; + + +class GLRendererPixelTest : public testing::Test { + protected: + GLRendererPixelTest() {} + + virtual void SetUp() { + gfx::InitializeGLBindings(gfx::kGLImplementationOSMesaGL); + output_surface_ = PixelTestOutputSurface::create(); + resource_provider_ = ResourceProvider::create(output_surface_.get()); + renderer_ = GLRenderer::create(&fake_client_, resource_provider_.get()); + } + + scoped_ptr<OutputSurface> output_surface_; + FakeRendererClient fake_client_; + scoped_ptr<ResourceProvider> resource_provider_; + scoped_ptr<GLRenderer> renderer_; +}; + +#if !defined(OS_ANDROID) +TEST_F(GLRendererPixelTest, simpleGreenRect) { + gfx::Rect rect(0, 0, 200, 200); + + RenderPass::Id id(1, 1); + const gfx::Rect output_rect = rect; + const gfx::RectF damage_rect = rect; + const gfx::Transform transform_to_root_target; + scoped_ptr<RenderPass> pass = RenderPass::Create(); + pass->SetNew(id, output_rect, damage_rect, transform_to_root_target); + + const gfx::Transform content_to_target_transform; + const gfx::Rect visible_content_rect = rect; + const gfx::Rect clipped_rect_in_target = rect; + const gfx::Rect clip_rect = rect; + const bool is_clipped = false; + const float opacity = 1.0f; + scoped_ptr<SharedQuadState> shared_state = SharedQuadState::Create(); + shared_state->SetAll(content_to_target_transform, + visible_content_rect, + clipped_rect_in_target, + clip_rect, + is_clipped, + opacity); + + scoped_ptr<SolidColorDrawQuad> color_quad = SolidColorDrawQuad::Create(); + color_quad->SetNew(shared_state.get(), rect, SK_ColorGREEN); + + pass->quad_list.append(color_quad.PassAs<DrawQuad>()); + + RenderPassList pass_list; + pass_list.push_back(pass.get()); + RenderPassIdHashMap pass_map; + pass_map.add(id, pass.PassAs<RenderPass>()); + + renderer_->drawFrame(pass_list, pass_map); + + SkBitmap bitmap; + bitmap.setConfig(SkBitmap::kARGB_8888_Config, 200, 200); + bitmap.allocPixels(); + unsigned char* pixels = static_cast<unsigned char*>(bitmap.getPixels()); + renderer_->getFramebufferPixels(pixels, gfx::Rect(0, 0, 200, 200)); + + FilePath test_data_dir; + ASSERT_TRUE(PathService::Get(cc::test::DIR_TEST_DATA, &test_data_dir)); + // test::WritePNGFile(bitmap, test_data_dir.AppendASCII("green.png")); + EXPECT_TRUE(test::IsSameAsPNGFile(bitmap, + test_data_dir.AppendASCII("green.png"))); +} +#endif + +} // namespace +} // namespace cc diff --git a/cc/layer_tree_host_perftest.cc b/cc/layer_tree_host_perftest.cc index d72c1bd..ca7031d 100644 --- a/cc/layer_tree_host_perftest.cc +++ b/cc/layer_tree_host_perftest.cc @@ -4,7 +4,6 @@ #include "cc/layer_tree_host.h" -#include "base/base_paths.h" #include "base/file_path.h" #include "base/file_util.h" #include "base/json/json_reader.h" @@ -15,6 +14,7 @@ #include "cc/solid_color_layer.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/layer_tree_test_common.h" +#include "cc/test/paths.h" namespace cc { namespace { @@ -240,12 +240,11 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { void readTestFile(std::string name) { test_name_ = name; - FilePath filepath; - ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &filepath)); - filepath = filepath.AppendASCII("cc").AppendASCII("test") - .AppendASCII("data").AppendASCII(name + ".json"); + FilePath test_data_dir; + ASSERT_TRUE(PathService::Get(cc::test::DIR_TEST_DATA, &test_data_dir)); + FilePath json_file = test_data_dir.AppendASCII(name + ".json"); std::string json; - ASSERT_TRUE(file_util::ReadFileToString(filepath, &json)); + ASSERT_TRUE(file_util::ReadFileToString(json_file, &json)); tree_.reset(base::JSONReader::Read(json)); ASSERT_TRUE(tree_); } diff --git a/cc/test/DEPS b/cc/test/DEPS new file mode 100644 index 0000000..76f1349 --- /dev/null +++ b/cc/test/DEPS @@ -0,0 +1,5 @@ +include_rules = [ + "+ui/gl/", +# TODO(jamesr): Remove once cc depends on GLES2Interface instead of WGC3D + "+webkit/gpu", +] diff --git a/cc/test/cc_test_suite.cc b/cc/test/cc_test_suite.cc new file mode 100644 index 0000000..9a43681 --- /dev/null +++ b/cc/test/cc_test_suite.cc @@ -0,0 +1,31 @@ +// 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 "cc/test/cc_test_suite.h" + +#include "base/message_loop.h" +#include "cc/test/paths.h" + +namespace cc { +namespace test { + +CCTestSuite::CCTestSuite(int argc, char** argv) + : base::TestSuite(argc, argv) {} + +CCTestSuite::~CCTestSuite() {} + +void CCTestSuite::Initialize() { + base::TestSuite::Initialize(); + RegisterPathProvider(); + message_loop_.reset(new MessageLoop); +} + +void CCTestSuite::Shutdown() { + message_loop_.reset(); + + base::TestSuite::Shutdown(); +} + +} // namespace test +} // namespace cc diff --git a/cc/test/cc_test_suite.h b/cc/test/cc_test_suite.h new file mode 100644 index 0000000..5cdf958 --- /dev/null +++ b/cc/test/cc_test_suite.h @@ -0,0 +1,36 @@ +// 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. + +#ifndef CC_TEST_CC_TEST_SUITE_H_ +#define CC_TEST_CC_TEST_SUITE_H_ + +#include "base/compiler_specific.h" +#include "base/memory/scoped_ptr.h" +#include "base/test/test_suite.h" + +class MessageLoop; + +namespace cc { +namespace test { + +class CCTestSuite : public base::TestSuite { + public: + CCTestSuite(int argc, char** argv); + virtual ~CCTestSuite(); + + protected: + // Overridden from base::TestSuite: + virtual void Initialize() OVERRIDE; + virtual void Shutdown() OVERRIDE; + + private: + scoped_ptr<MessageLoop> message_loop_; + + DISALLOW_COPY_AND_ASSIGN(CCTestSuite); +}; + +} // namespace test +} // namespace cc + +#endif // CC_TEST_CC_TEST_SUITE_H_ diff --git a/cc/test/paths.cc b/cc/test/paths.cc new file mode 100644 index 0000000..3551afb --- /dev/null +++ b/cc/test/paths.cc @@ -0,0 +1,44 @@ +// 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 "cc/test/paths.h" + +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/path_service.h" + +namespace cc { +namespace test { + +bool PathProvider(int key, FilePath* result) { + FilePath cur; + switch (key) { + // The following are only valid in the development environment, and + // will fail if executed from an installed executable (because the + // generated path won't exist). + case DIR_TEST_DATA: + if (!PathService::Get(base::DIR_SOURCE_ROOT, &cur)) + return false; + cur = cur.Append(FILE_PATH_LITERAL("cc")); + cur = cur.Append(FILE_PATH_LITERAL("test")); + cur = cur.Append(FILE_PATH_LITERAL("data")); + if (!file_util::PathExists(cur)) // we don't want to create this + return false; + break; + default: + return false; + } + + *result = cur; + return true; +} + +// This cannot be done as a static initializer sadly since Visual Studio will +// eliminate this object file if there is no direct entry point into it. +void RegisterPathProvider() { + PathService::RegisterProvider(PathProvider, PATH_START, PATH_END); +} + +} // namespace test +} // namespace cc diff --git a/cc/test/paths.h b/cc/test/paths.h new file mode 100644 index 0000000..bc3f4e0 --- /dev/null +++ b/cc/test/paths.h @@ -0,0 +1,26 @@ +// 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. + +#ifndef CC_TEST_PATHS_H_ +#define CC_TEST_PATHS_H_ + +namespace cc { +namespace test { + +enum { + PATH_START = 5000, + + // Valid only in development and testing environments. + DIR_TEST_DATA, + + PATH_END +}; + +// Call once to register the provider for the path keys defined above. +void RegisterPathProvider(); + +} // namespace test +} // namespace cc + +#endif // CC_TEST_PATHS_H_ diff --git a/cc/test/pixel_test_output_surface.cc b/cc/test/pixel_test_output_surface.cc new file mode 100644 index 0000000..46985b7 --- /dev/null +++ b/cc/test/pixel_test_output_surface.cc @@ -0,0 +1,36 @@ +// Copyright 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 "cc/test/pixel_test_output_surface.h" + +#include "webkit/gpu/webgraphicscontext3d_in_process_command_buffer_impl.h" + +namespace cc { + +PixelTestOutputSurface::PixelTestOutputSurface() { + scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl> + context(new webkit::gpu::WebGraphicsContext3DInProcessCommandBufferImpl); + context->Initialize(WebKit::WebGraphicsContext3D::Attributes(), NULL); + context_ = context.PassAs<WebKit::WebGraphicsContext3D>(); +} + +PixelTestOutputSurface::~PixelTestOutputSurface() { +} + +bool PixelTestOutputSurface::bindToClient( + WebKit::WebCompositorOutputSurfaceClient*) { + return context_->makeContextCurrent(); +} + +const WebKit::WebCompositorOutputSurface::Capabilities& + PixelTestOutputSurface::capabilities() const { + static WebKit::WebCompositorOutputSurface::Capabilities capabilities; + return capabilities; +} + +WebKit::WebGraphicsContext3D* PixelTestOutputSurface::context3D() const { + return context_.get(); +} + +} // namespace cc diff --git a/cc/test/pixel_test_output_surface.h b/cc/test/pixel_test_output_surface.h new file mode 100644 index 0000000..f59e63c --- /dev/null +++ b/cc/test/pixel_test_output_surface.h @@ -0,0 +1,37 @@ +// Copyright 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. + +#ifndef CC_TEST_PIXEL_TEST_GRAPHICS_CONTEXT_H_ +#define CC_TEST_PIXEL_TEST_GRAPHICS_CONTEXT_H_ + +#include "base/memory/scoped_ptr.h" +#include "cc/output_surface.h" + +namespace cc { + +class PixelTestOutputSurface : public OutputSurface { + public: + static scoped_ptr<PixelTestOutputSurface> create() { + return make_scoped_ptr(new PixelTestOutputSurface); + } + + virtual ~PixelTestOutputSurface(); + + // OutputSurface overrides. + virtual bool bindToClient(WebKit::WebCompositorOutputSurfaceClient*) OVERRIDE; + virtual const WebKit::WebCompositorOutputSurface::Capabilities& capabilities() const OVERRIDE; + virtual WebKit::WebGraphicsContext3D* context3D() const OVERRIDE; + virtual void sendFrameToParentCompositor( + const WebKit::WebCompositorFrame&) OVERRIDE { } + + private: + PixelTestOutputSurface(); + + scoped_ptr<WebKit::WebGraphicsContext3D> context_; +}; + +} // namespace cc + + +#endif // CC_TEST_PIXEL_TEST_GRAPHICS_CONTEXT_H_ diff --git a/cc/test/pixel_test_utils.cc b/cc/test/pixel_test_utils.cc new file mode 100644 index 0000000..ad455c0 --- /dev/null +++ b/cc/test/pixel_test_utils.cc @@ -0,0 +1,81 @@ +// 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 "cc/test/pixel_test_utils.h" + +#include "base/file_util.h" +#include "base/logging.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/gfx/codec/png_codec.h" + +namespace cc { +namespace test { + +bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path) { + std::vector<unsigned char> png_data; + const bool discard_transparency = true; + if (gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, + discard_transparency, + &png_data) && + file_util::CreateDirectory(file_path.DirName())) { + char* data = reinterpret_cast<char*>(&png_data[0]); + int size = static_cast<int>(png_data.size()); + return file_util::WriteFile(file_path, data, size) == size; + } + return false; +} + +bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap) { + DCHECK(bitmap); + std::string png_data; + return file_util::ReadFileToString(file_path, &png_data) && + gfx::PNGCodec::Decode(reinterpret_cast<unsigned char*>(&png_data[0]), + png_data.length(), + bitmap); +} + +bool IsSameAsPNGFile(const SkBitmap& gen_bmp, FilePath ref_img_path) { + SkBitmap ref_bmp; + if (!ReadPNGFile(ref_img_path, &ref_bmp)) { + LOG(ERROR) << "Cannot read reference image: " << ref_img_path.value(); + return false; + } + + if (ref_bmp.width() != gen_bmp.width() || + ref_bmp.height() != gen_bmp.height()) { + LOG(ERROR) + << "Dimensions do not match (Expected) vs (Actual):" + << "(" << ref_bmp.width() << "x" << ref_bmp.height() + << ") vs. " + << "(" << gen_bmp.width() << "x" << gen_bmp.height() << ")"; + return false; + } + + // Compare pixels and create a simple diff image. + int diff_pixels_count = 0; + SkAutoLockPixels lock_bmp(gen_bmp); + SkAutoLockPixels lock_ref_bmp(ref_bmp); + // The reference images were saved with no alpha channel. Use the mask to + // set alpha to 0. + uint32_t kAlphaMask = 0x00FFFFFF; + for (int x = 0; x < gen_bmp.width(); ++x) { + for (int y = 0; y < gen_bmp.height(); ++y) { + if ((*gen_bmp.getAddr32(x, y) & kAlphaMask) != + (*ref_bmp.getAddr32(x, y) & kAlphaMask)) { + ++diff_pixels_count; + } + } + } + + if (diff_pixels_count != 0) { + LOG(ERROR) << "Images differ by pixel count: " << diff_pixels_count; + return false; + } + + return true; +} + +} // namespace test +} // namespace cc + diff --git a/cc/test/pixel_test_utils.h b/cc/test/pixel_test_utils.h new file mode 100644 index 0000000..93367d8 --- /dev/null +++ b/cc/test/pixel_test_utils.h @@ -0,0 +1,25 @@ +// 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 "base/file_path.h" + +class SkBitmap; + +namespace cc { +namespace test { + +// Encodes a bitmap into a PNG and write to disk. Returns true on success. The +// parent directory does not have to exist. +bool WritePNGFile(const SkBitmap& bitmap, const FilePath& file_path); + +// Reads and decodes a PNG image to a bitmap. Returns true on success. The PNG +// should have been encoded using |gfx::PNGCodec::Encode|. +bool ReadPNGFile(const FilePath& file_path, SkBitmap* bitmap); + +// Compares with a PNG file on disk, and returns true if it is the same as +// the given image. |ref_img_path| is absolute. +bool IsSameAsPNGFile(const SkBitmap& gen_bmp, FilePath ref_img_path); + +} // namespace test +} // namespace cc diff --git a/cc/test/run_all_unittests.cc b/cc/test/run_all_unittests.cc index 4ea8697..40c224e 100644 --- a/cc/test/run_all_unittests.cc +++ b/cc/test/run_all_unittests.cc @@ -4,12 +4,12 @@ #include "base/message_loop.h" #include "base/test/test_suite.h" +#include "cc/test/cc_test_suite.h" #include "testing/gmock/include/gmock/gmock.h" int main(int argc, char** argv) { ::testing::InitGoogleMock(&argc, argv); - TestSuite test_suite(argc, argv); - MessageLoop message_loop; + cc::test::CCTestSuite test_suite(argc, argv); int result = test_suite.Run(); return result; |