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

Side by Side Diff: chrome/app/chrome_watcher_command_line_win_unittest.cc

Issue 1538923004: [win] Change Chrome Watcher configuration API. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix outdated comment. Created 4 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 | « chrome/app/chrome_watcher_command_line_win.cc ('k') | chrome/chrome_tests_unit.gypi » ('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 (c) 2014 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 "chrome/app/chrome_watcher_command_line_win.h"
6
7 #include <windows.h>
8
9 #include "base/command_line.h"
10 #include "base/files/file_path.h"
11 #include "base/process/process.h"
12 #include "base/process/process_handle.h"
13 #include "base/win/scoped_handle.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace {
17
18 base::FilePath ExampleExe() {
19 static const wchar_t kExampleExe[] = FILE_PATH_LITERAL("example.exe");
20 base::FilePath example_exe(kExampleExe);
21 return example_exe;
22 }
23
24 } // namespace
25
26 class TestChromeWatcherCommandLineGenerator
27 : public ChromeWatcherCommandLineGenerator {
28 public:
29 TestChromeWatcherCommandLineGenerator()
30 : ChromeWatcherCommandLineGenerator(ExampleExe()) {
31 }
32
33 // In the normal case the generator and interpreter are run in separate
34 // processes. However, since they are both being run in the same process in
35 // these tests the handle tracker will explode as they both claim ownership of
36 // the same handle. This function allows the generator handles to be released
37 // before they are subsequently claimed by an interpreter.
38 void ReleaseHandlesWithoutClosing() {
39 on_initialized_event_handle_.Take();
40 parent_process_handle_.Take();
41 }
42 };
43
44 // A fixture for tests that involve parsed command-lines. Contains utility
45 // functions for standing up a well-configured valid generator.
46 class ChromeWatcherCommandLineTest : public testing::Test {
47 public:
48 ChromeWatcherCommandLineTest()
49 : cmd_line_(base::CommandLine::NO_PROGRAM) {
50 }
51
52 void GenerateAndInterpretCommandLine() {
53 process_ = base::Process::OpenWithAccess(
54 base::GetCurrentProcId(), PROCESS_QUERY_INFORMATION | SYNCHRONIZE);
55 ASSERT_TRUE(process_.Handle());
56
57 event_.Set(::CreateEvent(nullptr, FALSE, FALSE, nullptr));
58 ASSERT_TRUE(event_.IsValid());
59
60 // The above handles are duplicated by the generator.
61 generator_.SetOnInitializedEventHandle(event_.Get());
62 generator_.SetParentProcessHandle(process_.Handle());
63
64 // Expect there to be two inherited handles created by the generator.
65 std::vector<HANDLE> handles;
66 generator_.GetInheritedHandles(&handles);
67 EXPECT_EQ(2U, handles.size());
68
69 cmd_line_ = generator_.GenerateCommandLine();
70
71 // In the normal case the generator and interpreter are run in separate
72 // processes. However, since they are both being run in the same process in
73 // this test that will lead to both the generator and the interpreter
74 // claiming ownership of the same handles, as far as the handle tracker is
75 // concerned. To prevent this the handles are first released from tracking
76 // by the generator.
77 generator_.ReleaseHandlesWithoutClosing();
78
79 interpreted_ = ChromeWatcherCommandLine::InterpretCommandLine(cmd_line_);
80 EXPECT_TRUE(interpreted_);
81 }
82
83 base::Process process_;
84 base::win::ScopedHandle event_;
85 TestChromeWatcherCommandLineGenerator generator_;
86 base::CommandLine cmd_line_;
87 scoped_ptr<ChromeWatcherCommandLine> interpreted_;
88 };
89
90 // The corresponding death test fixture.
91 using ChromeWatcherCommandLineDeathTest = ChromeWatcherCommandLineTest;
92
93 TEST(ChromeWatcherCommandLineGeneratorTest, UseOfBadHandlesFails) {
94 // Handles are always machine word aligned so there is no way these are valid.
95 HANDLE bad_handle_1 = reinterpret_cast<HANDLE>(0x01FC00B1);
96 HANDLE bad_handle_2 = reinterpret_cast<HANDLE>(0x01FC00B3);
97
98 // The above handles are duplicated by the generator.
99 TestChromeWatcherCommandLineGenerator generator;
100 EXPECT_FALSE(generator.SetOnInitializedEventHandle(bad_handle_1));
101 EXPECT_FALSE(generator.SetParentProcessHandle(bad_handle_2));
102
103 // Expect there to be no inherited handles created by the generator.
104 std::vector<HANDLE> handles;
105 generator.GetInheritedHandles(&handles);
106 EXPECT_TRUE(handles.empty());
107 }
108
109 TEST(ChromeWatcherCommandLineGeneratorTest, BadCommandLineFailsInterpretation) {
110 // Create an invalid command-line that is missing several fields.
111 base::CommandLine cmd_line(ExampleExe());
112
113 // Parse the command line.
114 auto interpreted = ChromeWatcherCommandLine::InterpretCommandLine(cmd_line);
115 EXPECT_FALSE(interpreted);
116 }
117
118 TEST_F(ChromeWatcherCommandLineDeathTest, HandlesLeftUntakenCausesDeath) {
119 EXPECT_NO_FATAL_FAILURE(GenerateAndInterpretCommandLine());
120
121 // Leave the handles in the interpreter and expect it to explode upon
122 // destruction.
123 EXPECT_DEATH(interpreted_.reset(), "Handles left untaken.");
124
125 // The above call to the destructor only runs in the context of the death test
126 // child process. To prevent the parent process from exploding in a similar
127 // fashion, release the handles so the destructor is happy.
128 interpreted_->TakeOnInitializedEventHandle().Close();
129 interpreted_->TakeParentProcessHandle().Close();
130 }
131
132 TEST_F(ChromeWatcherCommandLineTest, SuccessfulParse) {
133 EXPECT_NO_FATAL_FAILURE(GenerateAndInterpretCommandLine());
134
135 EXPECT_EQ(::GetCurrentThreadId(), interpreted_->main_thread_id());
136
137 // Explicitly take the handles from the interpreter so it doesn't explode.
138 base::win::ScopedHandle on_init =
139 interpreted_->TakeOnInitializedEventHandle();
140 base::win::ScopedHandle proc = interpreted_->TakeParentProcessHandle();
141 EXPECT_TRUE(on_init.IsValid());
142 EXPECT_TRUE(proc.IsValid());
143 }
144
145 // TODO(chrisha): Remove this test upon switching to using the new command-line
146 // classes.
147 TEST(OldChromeWatcherCommandLineTest, BasicTest) {
148 // Ownership of these handles is passed to the ScopedHandles below via
149 // InterpretChromeWatcherCommandLine().
150 base::ProcessHandle current =
151 ::OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE,
152 TRUE, // Inheritable.
153 ::GetCurrentProcessId());
154 ASSERT_NE(nullptr, current);
155
156 HANDLE event = ::CreateEvent(nullptr, FALSE, FALSE, nullptr);
157 ASSERT_NE(nullptr, event);
158 DWORD current_thread_id = ::GetCurrentThreadId();
159 base::CommandLine cmd_line = GenerateChromeWatcherCommandLine(
160 ExampleExe(), current, current_thread_id, event);
161
162 base::win::ScopedHandle current_result;
163 DWORD current_thread_id_result = 0;
164 base::win::ScopedHandle event_result;
165 ASSERT_TRUE(InterpretChromeWatcherCommandLine(
166 cmd_line, &current_result, &current_thread_id_result, &event_result));
167 ASSERT_EQ(current, current_result.Get());
168 ASSERT_EQ(current_thread_id, current_thread_id_result);
169 ASSERT_EQ(event, event_result.Get());
170 }
OLDNEW
« no previous file with comments | « chrome/app/chrome_watcher_command_line_win.cc ('k') | chrome/chrome_tests_unit.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698