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

Side by Side Diff: blimp/test/fake_engine/fake_engine_app_tests.cc

Issue 2626423004: Remove all //blimp code. (Closed)
Patch Set: One last(?) `git merge` for good measure. Created 3 years, 11 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
« no previous file with comments | « blimp/test/fake_engine/fake_engine.cc ('k') | blimp/test/fake_engine/fake_engine_main.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "blimp/test/fake_engine/fake_engine.h"
6
7 #include <fcntl.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10
11 #include "base/command_line.h"
12 #include "base/files/file_path.h"
13 #include "base/files/file_util.h"
14 #include "base/synchronization/waitable_event.h"
15 #include "base/test/launcher/unit_test_launcher.h"
16 #include "base/test/test_suite.h"
17 #include "blimp/test/fake_engine/proto/engine.grpc.pb.h"
18 #include "blimp/test/fake_engine/proto/lifetime.grpc.pb.h"
19 #include "blimp/test/fake_engine/proto/logging.grpc.pb.h"
20 #include "testing/gmock/include/gmock/gmock.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 #include "third_party/grpc/include/grpc++/create_channel_posix.h"
23 #include "third_party/grpc/include/grpc++/grpc++.h"
24 #include "third_party/grpc/include/grpc++/server_posix.h"
25
26 using ::testing::_;
27
28 namespace blimp {
29
30 namespace {
31
32 bool SocketPair(int* fd1, int* fd2) {
33 int pipe_fds[2];
34 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pipe_fds) != 0) {
35 PLOG(ERROR) << "socketpair()";
36 return false;
37 }
38
39 // Set both ends to be non-blocking.
40 if (fcntl(pipe_fds[0], F_SETFL, O_NONBLOCK) == -1 ||
41 fcntl(pipe_fds[1], F_SETFL, O_NONBLOCK) == -1) {
42 PLOG(ERROR) << "fcntl(O_NONBLOCK)";
43 if (IGNORE_EINTR(close(pipe_fds[0])) < 0)
44 PLOG(ERROR) << "close";
45 if (IGNORE_EINTR(close(pipe_fds[1])) < 0)
46 PLOG(ERROR) << "close";
47 return false;
48 }
49
50 *fd1 = pipe_fds[0];
51 *fd2 = pipe_fds[1];
52
53 return true;
54 }
55
56 class MockLifetimeService : public Lifetime::Service {
57 public:
58 MOCK_METHOD3(EngineReady, grpc::Status(
59 grpc::ServerContext*, const EngineReadyRequest*, EngineReadyResponse*));
60 };
61
62 class MockLoggingService : public Logging::Service {
63 public:
64 MOCK_METHOD3(Log, grpc::Status(
65 grpc::ServerContext*, const LogRequest*, LogResponse*));
66 };
67
68 // The FakeEngineAppTest suite sets up a simple interface resembling the
69 // Service, which is required by the Fake Engine. This allows testing whether
70 // the Fake Engine serves its purpose of simulating the real Engine as spawned
71 // by the Service.
72 class FakeEngineAppTest : public testing::Test {
73 public:
74 FakeEngineAppTest()
75 : engine_ready_(base::WaitableEvent::ResetPolicy::MANUAL,
76 base::WaitableEvent::InitialState::NOT_SIGNALED) {}
77
78 protected:
79 void SetUp() override {
80 CHECK(SocketPair(&rendering_server_connect_fd_, &engine_listen_fd_));
81 CHECK(SocketPair(&rendering_server_listen_fd_, &engine_connect_fd_));
82
83 grpc::ServerBuilder builder;
84 builder.RegisterService(&mock_lifetime_service_);
85 builder.RegisterService(&mock_logging_service_);
86 grpc_server_ = builder.BuildAndStart();
87
88 // TODO(xyzzyz): Remove fcntl when https://github.com/grpc/grpc/pull/8051 is
89 // merged and added to Chromium.
90 int flags = fcntl(rendering_server_listen_fd_, F_GETFL, 0);
91 CHECK_EQ(0, fcntl(rendering_server_listen_fd_, F_SETFL,
92 flags | O_NONBLOCK));
93
94 grpc::AddInsecureChannelFromFd(grpc_server_.get(),
95 rendering_server_listen_fd_);
96 }
97
98 // This function spawns a Fake Engine as a child process, and sets up the file
99 // descriptor mappings for it, resembling the mappings in the Service
100 // environment. It also sets up the handler for the EngineReady function that
101 // will be called by the Fake Engine upon startup.
102 base::Process SpawnEngine() {
103 // Find the path of the Engine.
104 base::CommandLine current_cmd = *base::CommandLine::ForCurrentProcess();
105 base::FilePath current_program_path = base::MakeAbsoluteFilePath(
106 current_cmd.GetProgram());
107 base::FilePath current_dir = current_program_path.DirName();
108 base::FilePath fake_engine_path = current_dir.Append("fake_engine_app");
109
110 base::CommandLine engine_cmd(fake_engine_path);
111
112 base::LaunchOptions options;
113 base::FileHandleMappingVector fds_to_remap = {
114 { engine_listen_fd_, kEngineListenFd },
115 { engine_connect_fd_, kRenderingServerListenFd }
116 };
117 options.fds_to_remap = &fds_to_remap;
118
119 ON_CALL(mock_lifetime_service_, EngineReady(_, _, _))
120 .WillByDefault(
121 testing::Invoke(this, &FakeEngineAppTest::EngineReadyHandler));
122 return base::LaunchProcess(engine_cmd, options);
123 }
124
125 grpc::Status EngineReadyHandler(
126 grpc::ServerContext*, const EngineReadyRequest*, EngineReadyResponse*) {
127 engine_ready_.Signal();
128 return grpc::Status::OK;
129 }
130
131 bool WaitForEngineReady(base::TimeDelta timeout) {
132 return engine_ready_.TimedWait(timeout);
133 }
134
135 std::unique_ptr<Engine::Stub> GetEngineStub() {
136 CHECK(!engine_channel_);
137 engine_channel_ = grpc::CreateInsecureChannelFromFd(
138 "fake_engine", rendering_server_connect_fd_);
139 CHECK(engine_channel_);
140 return Engine::NewStub(engine_channel_);
141 }
142
143 private:
144 int engine_listen_fd_;
145 int rendering_server_connect_fd_;
146
147 int rendering_server_listen_fd_;
148 int engine_connect_fd_;
149
150 std::unique_ptr<grpc::Server> grpc_server_;
151 MockLifetimeService mock_lifetime_service_;
152 MockLoggingService mock_logging_service_;
153
154 std::shared_ptr<grpc::Channel> engine_channel_;
155 base::WaitableEvent engine_ready_;
156
157 DISALLOW_COPY_AND_ASSIGN(FakeEngineAppTest);
158 };
159
160
161 TEST_F(FakeEngineAppTest, Basic) {
162 base::Process engine_process = SpawnEngine();
163 EXPECT_TRUE(WaitForEngineReady(base::TimeDelta::FromSeconds(5)));
164
165 std::unique_ptr<Engine::Stub> engine_stub = GetEngineStub();
166 {
167 CheckHealthRequest request;
168 CheckHealthResponse response;
169
170 grpc::ClientContext context;
171 grpc::Status status = engine_stub->CheckHealth(
172 &context, request, &response);
173 EXPECT_TRUE(status.ok());
174 EXPECT_EQ(response.status(), CheckHealthResponse::OK);
175 }
176
177 {
178 ShutDownRequest request;
179 ShutDownResponse response;
180
181 grpc::ClientContext context;
182 grpc::CompletionQueue cq;
183 // We do async call, as the Fake Engine doesn't send any reply to the
184 // ShutDown RPC, so it makes no sense to wait for it.
185 auto rpc = engine_stub->AsyncShutDown(&context, request, &cq);
186
187 EXPECT_TRUE(engine_process.WaitForExitWithTimeout(
188 base::TimeDelta::FromSeconds(5), nullptr /* exit_code */));
189 }
190 }
191
192 class FakeEngineTestSuite : public base::TestSuite {
193 public:
194 FakeEngineTestSuite(int argc, char** argv) : base::TestSuite(argc, argv) {}
195
196 protected:
197 void Initialize() override {
198 base::TestSuite::Initialize();
199 }
200
201 private:
202 DISALLOW_COPY_AND_ASSIGN(FakeEngineTestSuite);
203 };
204
205 } // namespace
206
207 } // namespace blimp
208
209 int main(int argc, char** argv) {
210 blimp::FakeEngineTestSuite test_suite(argc, argv);
211 return base::LaunchUnitTests(
212 argc, argv,
213 base::Bind(&base::TestSuite::Run, base::Unretained(&test_suite)));
214 }
OLDNEW
« no previous file with comments | « blimp/test/fake_engine/fake_engine.cc ('k') | blimp/test/fake_engine/fake_engine_main.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698