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

Side by Side Diff: services/native_support/process_impl_unittest.cc

Issue 1321253010: Add a "native_support" service. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fix android? Created 5 years, 2 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 2015 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 <string.h>
6
7 #include <memory>
8 #include <vector>
9
10 #include "base/message_loop/message_loop.h"
11 #include "mojo/public/cpp/bindings/interface_request.h"
12 #include "mojo/public/cpp/bindings/type_converter.h"
13 #include "mojo/public/cpp/system/macros.h"
14 #include "mojo/services/files/public/cpp/output_stream_file.h"
15 #include "mojo/services/files/public/interfaces/file.mojom.h"
16 #include "mojo/services/files/public/interfaces/types.mojom.h"
17 #include "services/native_support/process_test_base.h"
18
19 namespace native_support {
20 namespace {
21
22 using ProcessImplTest = ProcessTestBase;
23
24 // This also (slightly) tests |Wait()|, since we want to have some evidence that
25 // we ran the specified binary (/bin/true versus /bin/false).
26 TEST_F(ProcessImplTest, Spawn) {
27 mojo::files::Error error;
28
29 {
30 ProcessControllerPtr process_controller;
31 error = mojo::files::ERROR_INTERNAL;
32 process()->Spawn("/bin/true", mojo::Array<mojo::String>(),
33 mojo::Array<mojo::String>(), nullptr, nullptr, nullptr,
34 GetProxy(&process_controller), Capture(&error));
35 ASSERT_TRUE(process().WaitForIncomingResponse());
36 EXPECT_EQ(mojo::files::ERROR_OK, error);
37
38 error = mojo::files::ERROR_INTERNAL;
39 int32_t exit_status = 42;
40 process_controller->Wait(Capture(&error, &exit_status));
41 ASSERT_TRUE(process_controller.WaitForIncomingResponse());
42 EXPECT_EQ(mojo::files::ERROR_OK, error);
43 EXPECT_EQ(0, exit_status);
44 }
45
46 {
47 ProcessControllerPtr process_controller;
48 error = mojo::files::ERROR_INTERNAL;
49 process()->Spawn("/bin/false", mojo::Array<mojo::String>(),
50 mojo::Array<mojo::String>(), nullptr, nullptr, nullptr,
51 GetProxy(&process_controller), Capture(&error));
52 ASSERT_TRUE(process().WaitForIncomingResponse());
53 EXPECT_EQ(mojo::files::ERROR_OK, error);
54
55 error = mojo::files::ERROR_INTERNAL;
56 int32_t exit_status = 0;
57 process_controller->Wait(Capture(&error, &exit_status));
58 ASSERT_TRUE(process_controller.WaitForIncomingResponse());
59 EXPECT_EQ(mojo::files::ERROR_OK, error);
60 EXPECT_NE(exit_status, 0);
61 }
62 }
63
64 void QuitMessageLoop() {
65 base::MessageLoop::current()->QuitWhenIdle();
66 }
67
68 void RunMessageLoop() {
69 base::MessageLoop::current()->Run();
70 }
71
72 class CaptureOutputFile : public files_impl::OutputStreamFile::Client {
73 public:
74 explicit CaptureOutputFile(mojo::InterfaceRequest<mojo::files::File> request)
75 : impl_(files_impl::OutputStreamFile::Create(this, request.Pass())) {}
76 ~CaptureOutputFile() override {}
77
78 const std::string& output() const { return output_; }
79 bool is_closed() const { return is_closed_; }
80
81 private:
82 // |files_impl::OutputStreamFile::Client|:
83 void OnDataReceived(const void* bytes, size_t num_bytes) override {
84 output_.append(static_cast<const char*>(bytes), num_bytes);
85 QuitMessageLoop();
86 }
87 void OnClosed() override {
88 is_closed_ = true;
89 QuitMessageLoop();
90 }
91
92 std::string output_;
93 bool is_closed_ = false;
94 std::unique_ptr<files_impl::OutputStreamFile> impl_;
95
96 MOJO_DISALLOW_COPY_AND_ASSIGN(CaptureOutputFile);
97 };
98
99 // Spawn a native binary and redirect its stdout to a Mojo "file" that captures
100 // it.
101 TEST_F(ProcessImplTest, SpawnRedirectStdout) {
102 static const char kOutput[] = "hello mojo!";
103
104 mojo::files::FilePtr file;
105 CaptureOutputFile file_impl(GetProxy(&file));
106
107 mojo::Array<mojo::String> argv;
108 argv.push_back("/bin/echo");
109 argv.push_back(kOutput);
110 ProcessControllerPtr process_controller;
111 mojo::files::Error error = mojo::files::ERROR_INTERNAL;
112 process()->Spawn("/bin/echo", argv.Pass(), mojo::Array<mojo::String>(),
113 nullptr, file.Pass(), nullptr, GetProxy(&process_controller),
114 Capture(&error));
115 ASSERT_TRUE(process().WaitForIncomingResponse());
116 EXPECT_EQ(mojo::files::ERROR_OK, error);
117
118 // Since |file|'s impl is on our thread, we have to spin our message loop.
119 RunMessageLoop();
120 // /bin/echo adds a newline (alas, POSIX /bin/echo doesn't specify "-n").
121 EXPECT_EQ(std::string(kOutput) + "\n", file_impl.output());
122
123 error = mojo::files::ERROR_INTERNAL;
124 int32_t exit_status = 0;
125 process_controller->Wait(Capture(&error, &exit_status));
126 ASSERT_TRUE(process_controller.WaitForIncomingResponse());
127 EXPECT_EQ(mojo::files::ERROR_OK, error);
128 EXPECT_EQ(0, exit_status);
129
130 // TODO(vtl): Currently, |file| won't be closed until the process controller
131 // is closed, even if the child has been waited on and all output read.
132 // Possibly this should be changed, but we currently can't since the I/O
133 // thread doesn't have facilities for informing us that an FD will never be
134 // readable.
135 EXPECT_FALSE(file_impl.is_closed());
136 process_controller.reset();
137 RunMessageLoop();
138 EXPECT_TRUE(file_impl.is_closed());
139 }
140
141 } // namespace
142 } // namespace native_support
OLDNEW
« no previous file with comments | « services/native_support/process_impl.cc ('k') | services/native_support/process_io_redirection.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698