Refactor android test results logging.
[chromium-blink-merge.git] / ppapi / tests / test_case.cc
blobf6fb485687223161f431378606dcd123fd57db5e
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/tests/test_case.h"
7 #include <sstream>
9 #include "ppapi/tests/pp_thread.h"
10 #include "ppapi/tests/test_utils.h"
11 #include "ppapi/tests/testing_instance.h"
13 TestCase::TestCase(TestingInstance* instance)
14 : instance_(instance),
15 testing_interface_(NULL),
16 callback_type_(PP_REQUIRED) {
17 // Get the testing_interface_ if it is available, so that we can do Resource
18 // and Var checks on shutdown (see CheckResourcesAndVars). If it is not
19 // available, testing_interface_ will be NULL. Some tests do not require it.
20 testing_interface_ = GetTestingInterface();
23 TestCase::~TestCase() {
26 bool TestCase::Init() {
27 return true;
30 // static
31 std::string TestCase::MakeFailureMessage(const char* file,
32 int line,
33 const char* cmd) {
34 // The mere presence of this local variable works around a gcc-4.2.4
35 // compiler bug in official Chrome Linux builds. If you remove it,
36 // confirm this compile command still works:
37 // GYP_DEFINES='branding=Chrome buildtype=Official target_arch=x64'
38 // gclient runhooks
39 // make -k -j4 BUILDTYPE=Release ppapi_tests
40 std::string s;
42 std::ostringstream output;
43 output << "Failure in " << file << "(" << line << "): " << cmd;
44 return output.str();
47 #if !(defined __native_client__)
48 pp::VarPrivate TestCase::GetTestObject() {
49 if (test_object_.is_undefined()) {
50 pp::deprecated::ScriptableObject* so = CreateTestObject();
51 if (so) {
52 test_object_ = pp::VarPrivate(instance_, so); // Takes ownership.
53 // CheckResourcesAndVars runs and looks for leaks before we've actually
54 // completely shut down. Ignore the instance object, since it's not a real
55 // leak.
56 IgnoreLeakedVar(test_object_.pp_var().value.as_id);
59 return test_object_;
61 #endif
63 bool TestCase::CheckTestingInterface() {
64 testing_interface_ = GetTestingInterface();
65 if (!testing_interface_) {
66 // Give a more helpful error message for the testing interface being gone
67 // since that needs special enabling in Chrome.
68 instance_->AppendError("This test needs the testing interface, which is "
69 "not currently available. In Chrome, use "
70 "--enable-pepper-testing when launching.");
71 return false;
74 return true;
77 void TestCase::HandleMessage(const pp::Var& message_data) {
80 void TestCase::DidChangeView(const pp::View& view) {
83 bool TestCase::HandleInputEvent(const pp::InputEvent& event) {
84 return false;
87 void TestCase::IgnoreLeakedVar(int64_t id) {
88 ignored_leaked_vars_.insert(id);
91 #if !(defined __native_client__)
92 pp::deprecated::ScriptableObject* TestCase::CreateTestObject() {
93 return NULL;
95 #endif
97 bool TestCase::EnsureRunningOverHTTP() {
98 if (instance_->protocol() != "http:") {
99 instance_->AppendError("This test needs to be run over HTTP.");
100 return false;
103 return true;
106 bool TestCase::MatchesFilter(const std::string& test_name,
107 const std::string& filter) {
108 return filter.empty() || (test_name == filter);
111 std::string TestCase::CheckResourcesAndVars(std::string errors) {
112 if (!errors.empty())
113 return errors;
115 if (testing_interface_) {
116 // TODO(dmichael): Fix tests that leak resources and enable the following:
118 uint32_t leaked_resources =
119 testing_interface_->GetLiveObjectsForInstance(instance_->pp_instance());
120 if (leaked_resources) {
121 std::ostringstream output;
122 output << "FAILED: Test leaked " << leaked_resources << " resources.\n";
123 errors += output.str();
126 const int kVarsToPrint = 100;
127 PP_Var vars[kVarsToPrint];
128 int found_vars = testing_interface_->GetLiveVars(vars, kVarsToPrint);
129 // This will undercount if we are told to ignore a Var which is then *not*
130 // leaked. Worst case, we just won't print the little "Test leaked" message,
131 // but we'll still print any non-ignored leaked vars we found.
132 int leaked_vars =
133 found_vars - static_cast<int>(ignored_leaked_vars_.size());
134 if (leaked_vars > 0) {
135 std::ostringstream output;
136 output << "Test leaked " << leaked_vars << " vars (printing at most "
137 << kVarsToPrint <<"):<p>";
138 errors += output.str();
140 for (int i = 0; i < std::min(found_vars, kVarsToPrint); ++i) {
141 pp::Var leaked_var(pp::PASS_REF, vars[i]);
142 if (ignored_leaked_vars_.count(leaked_var.pp_var().value.as_id) == 0)
143 errors += leaked_var.DebugString() + "<p>";
146 return errors;
149 // static
150 void TestCase::QuitMainMessageLoop(PP_Instance instance) {
151 PP_Instance* heap_instance = new PP_Instance(instance);
152 pp::CompletionCallback callback(&DoQuitMainMessageLoop, heap_instance);
153 pp::Module::Get()->core()->CallOnMainThread(0, callback);
156 // static
157 void TestCase::DoQuitMainMessageLoop(void* pp_instance, int32_t result) {
158 PP_Instance* instance = static_cast<PP_Instance*>(pp_instance);
159 GetTestingInterface()->QuitMessageLoop(*instance);
160 delete instance;
163 void TestCase::RunOnThreadInternal(void (*thread_func)(void*),
164 void* thread_param,
165 const PPB_Testing_Dev* testing_interface) {
166 PP_ThreadType thread;
167 PP_CreateThread(&thread, thread_func, thread_param);
168 // Run a message loop so pepper calls can be dispatched. The background
169 // thread will set result_ and make us Quit when it's done.
170 testing_interface->RunMessageLoop(instance_->pp_instance());
171 PP_JoinThread(thread);