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

Side by Side Diff: services/ui/ws/gpu_host_unittest.cc

Issue 2741343003: Update liftetime management of GpuClient (Closed)
Patch Set: missing deps: Created 3 years, 9 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
OLDNEW
(Empty)
1 // Copyright 2017 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.
4
5 #include "services/ui/ws/gpu_host.h"
6
7 #include "base/macros.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/memory/ref_counted.h"
10 #include "base/memory/weak_ptr.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/test/test_simple_task_runner.h"
13 #include "gpu/config/gpu_info.h"
14 #include "gpu/ipc/service/gpu_watchdog_thread.h"
15 #include "services/ui/gpu/gpu_service.h"
16 #include "services/ui/public/interfaces/gpu.mojom.h"
17 #include "services/ui/ws/gpu_host_delegate.h"
18 #include "testing/gtest/include/gtest/gtest.h"
19
20 namespace ui {
21 namespace ws {
22 namespace test {
23 namespace {
24
25 // No-opt implementation of GpuHostDelegate.
26 class TestGpuHostDelegate : public GpuHostDelegate {
27 public:
28 TestGpuHostDelegate() {}
29 ~TestGpuHostDelegate() override {}
30
31 void OnGpuServiceInitialized() override {}
32
33 private:
34 DISALLOW_COPY_AND_ASSIGN(TestGpuHostDelegate);
35 };
36
37 // Test implementation of GpuService. For testing behaviour of calls made by
38 // GpuHost::GpuClient
39 class TestGpuService : public GpuService {
40 public:
41 TestGpuService(scoped_refptr<base::TestSimpleTaskRunner> task_runner);
42 ~TestGpuService() override {}
43
44 bool establish_gpu_called() { return establish_gpu_called_; }
45
46 // Sets callback for providing test implementation of EstablishGpuChannel/
47 void SetEstablishGpuChannelTestCallback(base::Closure callback) {
48 establish_gpu_channel_callback_ = callback;
49 }
50
51 // GpuService:
52 void EstablishGpuChannel(
53 int32_t client_id,
54 uint64_t client_tracing_id,
55 bool is_gpu_host,
56 const EstablishGpuChannelCallback& callback) override;
57
58 private:
59 base::Closure establish_gpu_channel_callback_;
60
61 bool establish_gpu_called_ = false;
62
63 DISALLOW_COPY_AND_ASSIGN(TestGpuService);
64 };
65
66 TestGpuService::TestGpuService(
67 scoped_refptr<base::TestSimpleTaskRunner> task_runner)
68 : GpuService(gpu::GPUInfo(),
69 gpu::GpuWatchdogThread::Create(),
70 nullptr,
71 task_runner,
72 gpu::GpuFeatureInfo()) {}
73
74 void TestGpuService::EstablishGpuChannel(
75 int32_t client_id,
76 uint64_t client_tracing_id,
77 bool is_gpu_host,
78 const EstablishGpuChannelCallback& callback) {
79 establish_gpu_called_ = true;
80 EXPECT_FALSE(establish_gpu_channel_callback_.is_null());
81 EXPECT_FALSE(callback.is_null());
82 EXPECT_FALSE(callback.IsCancelled());
83 establish_gpu_channel_callback_.Run();
84 // Calling should not lead to a crash.
85 callback.Run(mojo::ScopedMessagePipeHandle());
86 }
87
88 // While provide to GpuClient as a callback, actually calling into this during
89 // the test would lead to a use-after-free. This will explicitly crash to detect
90 // the error on non-asan builds.
91 void CrashOnCallback(int32_t client_id,
92 mojo::ScopedMessagePipeHandle channel_handle,
93 const gpu::GPUInfo& gpu_info) {
94 CHECK(false);
95 }
96
97 } // namespace
98
99 class GpuHostTest : public testing::Test {
100 public:
101 GpuHostTest();
102 ~GpuHostTest() override {}
103
104 GpuHost* gpu_host() { return gpu_host_.get(); }
105
106 // Implementations for corresponding tests.
107 void TestGpuClientDestructionOrder();
108 void TestHostDeletionInvalidatesGpuClientCallback();
109
110 // Deletes |gpu_host_| and verifies that |client_ref_| has cleaned up.
111 void DeleteHostAndVerifyClientDeleted();
112
113 // testing::Test
114 void SetUp() override;
115
116 private:
117 base::MessageLoop message_loop_;
118 scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
119
120 base::WeakPtr<GpuHost::GpuClient> client_ref_;
121
122 TestGpuHostDelegate gpu_host_delegate_;
123 TestGpuService gpu_service_;
124 ui::mojom::GpuServicePtr gpu_service_ptr_;
125 std::unique_ptr<GpuHost> gpu_host_;
126
127 DISALLOW_COPY_AND_ASSIGN(GpuHostTest);
128 };
129
130 GpuHostTest::GpuHostTest()
131 : task_runner_(new base::TestSimpleTaskRunner), gpu_service_(task_runner_) {
sadrul 2017/03/22 16:42:04 Is there a reason to set this task runner? Can you
jonross 2017/03/23 00:38:29 Allows for manually advancing posted tasks in an i
132 message_loop_.SetTaskRunner(task_runner_);
133 }
134
135 void GpuHostTest::TestGpuClientDestructionOrder() {
136 mojom::GpuRequest request;
137 GpuHost::GpuClient* client = static_cast<GpuHost::GpuClient*>(
138 gpu_host_->AddInternal(std::move(request)));
139 client_ref_ = client->AsWeakPtr();
140 // Closing the host should shutdown the GpuClient.
141 gpu_host_.reset();
142 // If |client_ref| is not deleted the subsequent call will reproduce the
143 // use-after-free of GpuHost's GpuInfo.
144 if (client_ref_) {
145 // Passing in a callback which crashes to identify the error on non-asan
146 // builds.
147 client_ref_->OnGpuChannelEstablished(base::Bind(&CrashOnCallback),
148 mojo::ScopedMessagePipeHandle());
149 }
150 EXPECT_EQ(nullptr, client_ref_);
sadrul 2017/03/22 16:41:13 This the expectation, right? i.e. when GpuHost is
jonross 2017/03/22 16:49:43 I had originally used the CrashOnCallback to confi
jonross 2017/03/23 00:38:29 Done.
151 }
152
153 void GpuHostTest::TestHostDeletionInvalidatesGpuClientCallback() {
154 mojom::GpuRequest request;
155 GpuHost::GpuClient* client = static_cast<GpuHost::GpuClient*>(
156 gpu_host_->AddInternal(std::move(request)));
sadrul 2017/03/22 16:41:13 Make the return type GpuClient* so you don't need
jonross 2017/03/23 00:38:29 Done.
157 client_ref_ = client->AsWeakPtr();
158
159 // Second stage of test is DeleteHostAndVerifyClientDeleted invoked by
160 // TestGpuService.
161 gpu_service_.SetEstablishGpuChannelTestCallback(base::Bind(
162 &GpuHostTest::DeleteHostAndVerifyClientDeleted, base::Unretained(this)));
163 client->EstablishGpuChannel(base::Bind(&CrashOnCallback));
164 // TestGpuService will be notified of above in a posted task.
165 task_runner_->RunPendingTasks();
166 EXPECT_TRUE(gpu_service_.establish_gpu_called());
sadrul 2017/03/22 16:41:13 This is still essentially testing that destroying
jonross 2017/03/22 16:49:43 The other test is a simple verification of that.
jonross 2017/03/23 00:38:29 Done.
167 }
168
169 void GpuHostTest::DeleteHostAndVerifyClientDeleted() {
170 EXPECT_NE(nullptr, client_ref_);
171 gpu_host_.reset();
172 task_runner_->RunPendingTasks();
173 // Verifies cleanup of the GpuClient, which prevents callbacks from resolving.
174 EXPECT_EQ(nullptr, client_ref_);
175 }
176
177 void GpuHostTest::SetUp() {
178 testing::Test::SetUp();
179 gpu_host_ = base::MakeUnique<GpuHost>(&gpu_host_delegate_);
180
181 ui::mojom::GpuServiceRequest request(&gpu_service_ptr_);
182 gpu_service_.Bind(std::move(request));
183 gpu_host_->gpu_service_ = std::move(gpu_service_ptr_);
184 }
185
186 // Tests to verify, that if a GpuHost is deleted before GpuClient receives a
187 // callback, that GpuClient is torn down and does not attempt to use GpuInfo
188 // after deletion. This should not crash on asan-builds.
189 TEST_F(GpuHostTest, GpuClientDestructionOrder) {
190 TestGpuClientDestructionOrder();
sadrul 2017/03/22 16:41:13 Why a separate function for each test?
jonross 2017/03/22 16:49:43 They each are calling several private methods. I c
jonross 2017/03/23 00:38:29 Actually the reduced test has less requirements of
191 }
192
193 // Tests that if GpuHost is deleted that callbacks provided by GpuClient are
194 // invalidated and do not cause crashes.
195 TEST_F(GpuHostTest, HostDeletionInvalidatesGpuClientCallback) {
196 TestHostDeletionInvalidatesGpuClientCallback();
197 }
198
199 } // namespace test
200 } // namespace ws
201 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698