Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(773)

Side by Side Diff: ppapi/tests/test_instance_deprecated.cc

Issue 472693002: Minor changes to allow Pepper InstancePrivate tests to pass with gin (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/tests/test_instance_deprecated.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ppapi/tests/test_instance_deprecated.h" 5 #include "ppapi/tests/test_instance_deprecated.h"
6 6
7 #include <assert.h> 7 #include <assert.h>
8 8
9 #include "ppapi/c/ppb_var.h" 9 #include "ppapi/c/ppb_var.h"
10 #include "ppapi/cpp/module.h" 10 #include "ppapi/cpp/module.h"
11 #include "ppapi/cpp/dev/scriptable_object_deprecated.h" 11 #include "ppapi/cpp/dev/scriptable_object_deprecated.h"
12 #include "ppapi/tests/testing_instance.h" 12 #include "ppapi/tests/testing_instance.h"
13 13
14 namespace { 14 namespace {
15 15
16 static const char kSetValueFunction[] = "SetValue"; 16 static const char kSetValueFunction[] = "SetValue";
17 static const char kSetExceptionFunction[] = "SetException"; 17 static const char kSetExceptionFunction[] = "SetException";
18 static const char kReturnValueFunction[] = "ReturnValue"; 18 static const char kReturnValueFunction[] = "ReturnValue";
19 19
20 // ScriptableObject used by instance.
21 class InstanceSO : public pp::deprecated::ScriptableObject {
22 public:
23 explicit InstanceSO(TestInstance* i);
24 virtual ~InstanceSO();
25
26 // pp::deprecated::ScriptableObject overrides.
27 bool HasMethod(const pp::Var& name, pp::Var* exception);
28 pp::Var Call(const pp::Var& name,
29 const std::vector<pp::Var>& args,
30 pp::Var* exception);
31
32 private:
33 TestInstance* test_instance_;
34 // For out-of-process, the InstanceSO might be deleted after the instance was
35 // already destroyed, so we can't rely on test_instance_->testing_interface()
36 // being valid. Therefore we store our own.
37 const PPB_Testing_Private* testing_interface_;
38 };
39
40 InstanceSO::InstanceSO(TestInstance* i) 20 InstanceSO::InstanceSO(TestInstance* i)
41 : test_instance_(i), 21 : test_instance_(i),
42 testing_interface_(i->testing_interface()) { 22 testing_interface_(i->testing_interface()) {
43 // Set up a post-condition for the test so that we can ensure our destructor 23 if (testing_interface_->IsOutOfProcess() == PP_FALSE)
44 // is called. This only works reliably in-process. Out-of-process, it only 24 test_instance_->set_instance_object_destroyed(false);
45 // can work when the renderer stays alive a short while after the plugin
46 // instance is destroyed. If the renderer is being shut down, too much happens
47 // asynchronously for the out-of-process case to work reliably. In
48 // particular:
49 // - The Var ReleaseObject message is asynchronous.
50 // - The PPB_Var_Deprecated host-side proxy posts a task to actually release
51 // the object when the ReleaseObject message is received.
52 // - The PPP_Class Deallocate message is asynchronous.
53 // At time of writing this comment, if you modify the code so that the above
54 // happens synchronously, and you remove the restriction that the plugin can't
55 // be unblocked by a sync message, then this check actually passes reliably
56 // for out-of-process. But we don't want to make any of those changes, so we
57 // just skip the check.
58 if (testing_interface_->IsOutOfProcess() == PP_FALSE) {
59 i->instance()->AddPostCondition(
60 "window.document.getElementById('container').instance_object_destroyed"
61 );
62 }
63 } 25 }
64 26
65 InstanceSO::~InstanceSO() { 27 InstanceSO::~InstanceSO() {
66 if (testing_interface_->IsOutOfProcess() == PP_FALSE) { 28 if (test_instance_)
67 // TODO(dmichael): It would probably be best to make in-process consistent 29 test_instance_->set_instance_object_destroyed(true);
68 // with out-of-process. That would mean that the instance
69 // would already be destroyed at this point.
70 pp::Var ret = test_instance_->instance()->ExecuteScript(
71 "document.getElementById('container').instance_object_destroyed=true;");
72 } else {
73 // Out-of-process, this destructor might not actually get invoked. See the
74 // comment in InstanceSO's constructor for an explanation. Also, instance()
75 // has already been destroyed :-(. So we can't really do anything here.
76 }
77 } 30 }
78 31
79 bool InstanceSO::HasMethod(const pp::Var& name, pp::Var* exception) { 32 bool InstanceSO::HasMethod(const pp::Var& name, pp::Var* exception) {
80 if (!name.is_string()) 33 if (!name.is_string())
81 return false; 34 return false;
82 return name.AsString() == kSetValueFunction || 35 return name.AsString() == kSetValueFunction ||
83 name.AsString() == kSetExceptionFunction || 36 name.AsString() == kSetExceptionFunction ||
84 name.AsString() == kReturnValueFunction; 37 name.AsString() == kReturnValueFunction;
85 } 38 }
86 39
87 pp::Var InstanceSO::Call(const pp::Var& method_name, 40 pp::Var InstanceSO::Call(const pp::Var& method_name,
88 const std::vector<pp::Var>& args, 41 const std::vector<pp::Var>& args,
89 pp::Var* exception) { 42 pp::Var* exception) {
90 if (!method_name.is_string()) 43 if (!method_name.is_string())
91 return false; 44 return false;
92 std::string name = method_name.AsString(); 45 std::string name = method_name.AsString();
93 46
94 if (name == kSetValueFunction) { 47 if (name == kSetValueFunction) {
95 if (args.size() != 1 || !args[0].is_string()) 48 if (args.size() != 1 || !args[0].is_string())
96 *exception = pp::Var("Bad argument to SetValue(<string>)"); 49 *exception = pp::Var("Bad argument to SetValue(<string>)");
97 else 50 else if (test_instance_)
98 test_instance_->set_string(args[0].AsString()); 51 test_instance_->set_string(args[0].AsString());
99 } else if (name == kSetExceptionFunction) { 52 } else if (name == kSetExceptionFunction) {
100 if (args.size() != 1 || !args[0].is_string()) 53 if (args.size() != 1 || !args[0].is_string())
101 *exception = pp::Var("Bad argument to SetException(<string>)"); 54 *exception = pp::Var("Bad argument to SetException(<string>)");
102 else 55 else
103 *exception = args[0]; 56 *exception = args[0];
104 } else if (name == kReturnValueFunction) { 57 } else if (name == kReturnValueFunction) {
105 if (args.size() != 1) 58 if (args.size() != 1)
106 *exception = pp::Var("Need single arg to call ReturnValue"); 59 *exception = pp::Var("Need single arg to call ReturnValue");
107 else 60 else
108 return args[0]; 61 return args[0];
109 } else { 62 } else {
110 *exception = pp::Var("Bad function call"); 63 *exception = pp::Var("Bad function call");
111 } 64 }
112 65
113 return pp::Var(); 66 return pp::Var();
114 } 67 }
115 68
116 } // namespace 69 } // namespace
117 70
118 REGISTER_TEST_CASE(Instance); 71 REGISTER_TEST_CASE(Instance);
119 72
120 TestInstance::TestInstance(TestingInstance* instance) : TestCase(instance) { 73 TestInstance::TestInstance(TestingInstance* instance)
121 } 74 : TestCase(instance),
75 instance_so_(NULL) {}
122 76
123 bool TestInstance::Init() { 77 bool TestInstance::Init() {
124 return true; 78 return true;
125 } 79 }
126 80
127 TestInstance::~TestInstance() { 81 TestInstance::~TestInstance() {
128 ResetTestObject(); 82 ResetTestObject();
129 // When running tests in process, some post conditions check that teardown 83 if (testing_interface_->IsOutOfProcess() == PP_FALSE) {
130 // happened successfully. We need to run the garbage collector to ensure that 84 // This should cause the instance objects descructor to be called.
Sam McNally 2014/08/27 04:45:51 objects descructor -> object's destructor
131 // vars get released.
132 if (testing_interface_->IsOutOfProcess() == PP_FALSE)
133 testing_interface_->RunV8GC(instance_->pp_instance()); 85 testing_interface_->RunV8GC(instance_->pp_instance());
86
87 // Test a post-condition which ensures the instance objects destructor is
88 // called. This only works reliably in-process. Out-of-process, it only
89 // can work when the renderer stays alive a short while after the plugin
90 // instance is destroyed. If the renderer is being shut down, too much
91 // happens asynchronously for the out-of-process case to work reliably. In
92 // particular:
93 // - The Var ReleaseObject message is asynchronous.
94 // - The PPB_Var_Deprecated host-side proxy posts a task to actually
95 // release the object when the ReleaseObject message is received.
96 // - The PPP_Class Deallocate message is asynchronous.
97 // At time of writing this comment, if you modify the code so that the above
98 // happens synchronously, and you remove the restriction that the plugin
99 // can't be unblocked by a sync message, then this check actually passes
100 // reliably for out-of-process. But we don't want to make any of those
101 // changes so we just skip the check.
102 PP_DCHECK(!instance_so_);
103 } else {
104 // Out-of-process, this destructor might not actually get invoked. Clear
105 // the InstanceSOs reference to the instance so there is no UAF.
106 if (instance_so_)
107 instance_so_->clear_test_instance();
108 }
109
134 // Save the fact that we were destroyed in sessionStorage. This tests that 110 // Save the fact that we were destroyed in sessionStorage. This tests that
135 // we can ExecuteScript at instance destruction without crashing. It also 111 // we can ExecuteScript at instance destruction without crashing. It also
136 // allows us to check that ExecuteScript will run and succeed in certain 112 // allows us to check that ExecuteScript will run and succeed in certain
137 // cases. In particular, when the instance is destroyed by normal DOM 113 // cases. In particular, when the instance is destroyed by normal DOM
138 // deletion, ExecuteScript will actually work. See 114 // deletion, ExecuteScript will actually work. See
139 // TestExecuteScriptInInstanceShutdown for that test. Note, however, that 115 // TestExecuteScriptInInstanceShutdown for that test. Note, however, that
140 // ExecuteScript will *not* have an effect when the instance is destroyed 116 // ExecuteScript will *not* have an effect when the instance is destroyed
141 // because the renderer was shut down. 117 // because the renderer was shut down.
142 pp::Var ret = instance()->ExecuteScript( 118 pp::Var ret = instance()->ExecuteScript(
143 "sessionStorage.setItem('instance_destroyed', 'true');"); 119 "sessionStorage.setItem('instance_destroyed', 'true');");
144 } 120 }
145 121
146 void TestInstance::RunTests(const std::string& filter) { 122 void TestInstance::RunTests(const std::string& filter) {
147 RUN_TEST(ExecuteScript, filter); 123 RUN_TEST(ExecuteScript, filter);
148 RUN_TEST(RecursiveObjects, filter); 124 RUN_TEST(RecursiveObjects, filter);
149 RUN_TEST(LeakedObjectDestructors, filter); 125 RUN_TEST(LeakedObjectDestructors, filter);
150 RUN_TEST(SetupExecuteScriptAtInstanceShutdown, filter); 126 RUN_TEST(SetupExecuteScriptAtInstanceShutdown, filter);
151 RUN_TEST(ExecuteScriptAtInstanceShutdown, filter); 127 RUN_TEST(ExecuteScriptAtInstanceShutdown, filter);
152 } 128 }
153 129
154 void TestInstance::LeakReferenceAndIgnore(const pp::Var& leaked) { 130 void TestInstance::LeakReferenceAndIgnore(const pp::Var& leaked) {
155 static const PPB_Var* var_interface = static_cast<const PPB_Var*>( 131 static const PPB_Var* var_interface = static_cast<const PPB_Var*>(
156 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE)); 132 pp::Module::Get()->GetBrowserInterface(PPB_VAR_INTERFACE));
157 var_interface->AddRef(leaked.pp_var()); 133 var_interface->AddRef(leaked.pp_var());
158 IgnoreLeakedVar(leaked.pp_var().value.as_id); 134 IgnoreLeakedVar(leaked.pp_var().value.as_id);
159 } 135 }
160 136
161 pp::deprecated::ScriptableObject* TestInstance::CreateTestObject() { 137 pp::deprecated::ScriptableObject* TestInstance::CreateTestObject() {
162 return new InstanceSO(this); 138 if (!instance_so_)
139 instance_so_ = new InstanceSO(this);
140 return instance_so_;
163 } 141 }
164 142
165 std::string TestInstance::TestExecuteScript() { 143 std::string TestInstance::TestExecuteScript() {
166 // Simple call back into the plugin. 144 // Simple call back into the plugin.
167 pp::Var exception; 145 pp::Var exception;
168 pp::Var ret = instance_->ExecuteScript( 146 pp::Var ret = instance_->ExecuteScript(
169 "document.getElementById('plugin').SetValue('hello, world');", 147 "document.getElementById('plugin').SetValue('hello, world');",
170 &exception); 148 &exception);
171 ASSERT_TRUE(ret.is_undefined()); 149 ASSERT_TRUE(ret.is_undefined());
172 ASSERT_TRUE(exception.is_undefined()); 150 ASSERT_TRUE(exception.is_undefined());
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
292 // that it was set as expected. 270 // that it was set as expected.
293 pp::Var result = instance()->ExecuteScript( 271 pp::Var result = instance()->ExecuteScript(
294 "sessionStorage.getItem('instance_destroyed');"); 272 "sessionStorage.getItem('instance_destroyed');");
295 ASSERT_TRUE(result.is_string()); 273 ASSERT_TRUE(result.is_string());
296 ASSERT_EQ(std::string("true"), result.AsString()); 274 ASSERT_EQ(std::string("true"), result.AsString());
297 instance()->ExecuteScript("sessionStorage.removeItem('instance_destroyed');"); 275 instance()->ExecuteScript("sessionStorage.removeItem('instance_destroyed');");
298 276
299 PASS(); 277 PASS();
300 } 278 }
301 279
OLDNEW
« no previous file with comments | « ppapi/tests/test_instance_deprecated.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698