OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 // This file contains unit tests for the job object. | |
6 | |
7 #include "base/win/scoped_process_information.h" | |
8 #include "sandbox/src/job.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 | |
11 namespace sandbox { | |
12 | |
13 // Tests the creation and destruction of the job. | |
14 TEST(JobTest, TestCreation) { | |
15 // Scope the creation of Job. | |
16 { | |
17 // Create the job. | |
18 Job job; | |
19 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0)); | |
20 | |
21 // check if the job exists. | |
22 HANDLE job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE, | |
23 L"my_test_job_name"); | |
24 ASSERT_TRUE(job_handle != NULL); | |
25 | |
26 if (job_handle) | |
27 CloseHandle(job_handle); | |
28 } | |
29 | |
30 // Check if the job is destroyed when the object goes out of scope. | |
31 HANDLE job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE, L"my_test_job_name"); | |
32 ASSERT_TRUE(job_handle == NULL); | |
33 ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError()); | |
34 } | |
35 | |
36 // Tests the method "Detach". | |
37 TEST(JobTest, TestDetach) { | |
38 HANDLE job_handle; | |
39 // Scope the creation of Job. | |
40 { | |
41 // Create the job. | |
42 Job job; | |
43 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0)); | |
44 | |
45 job_handle = job.Detach(); | |
46 ASSERT_TRUE(job_handle != NULL); | |
47 } | |
48 | |
49 // Check to be sure that the job is still alive even after the object is gone | |
50 // out of scope. | |
51 HANDLE job_handle_dup = ::OpenJobObjectW(GENERIC_ALL, FALSE, | |
52 L"my_test_job_name"); | |
53 ASSERT_TRUE(job_handle_dup != NULL); | |
54 | |
55 // Remove all references. | |
56 if (job_handle_dup) | |
57 ::CloseHandle(job_handle_dup); | |
58 | |
59 if (job_handle) | |
60 ::CloseHandle(job_handle); | |
61 | |
62 // Check if the jbo is really dead. | |
63 job_handle = ::OpenJobObjectW(GENERIC_ALL, FALSE, L"my_test_job_name"); | |
64 ASSERT_TRUE(job_handle == NULL); | |
65 ASSERT_EQ(ERROR_FILE_NOT_FOUND, ::GetLastError()); | |
66 } | |
67 | |
68 // Tests the ui exceptions | |
69 TEST(JobTest, TestExceptions) { | |
70 HANDLE job_handle; | |
71 // Scope the creation of Job. | |
72 { | |
73 // Create the job. | |
74 Job job; | |
75 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", | |
76 JOB_OBJECT_UILIMIT_READCLIPBOARD)); | |
77 | |
78 job_handle = job.Detach(); | |
79 ASSERT_TRUE(job_handle != NULL); | |
80 | |
81 JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0}; | |
82 DWORD size = sizeof(jbur); | |
83 BOOL result = ::QueryInformationJobObject(job_handle, | |
84 JobObjectBasicUIRestrictions, | |
85 &jbur, size, &size); | |
86 ASSERT_TRUE(result); | |
87 | |
88 ASSERT_EQ(jbur.UIRestrictionsClass & JOB_OBJECT_UILIMIT_READCLIPBOARD, 0); | |
89 ::CloseHandle(job_handle); | |
90 } | |
91 | |
92 // Scope the creation of Job. | |
93 { | |
94 // Create the job. | |
95 Job job; | |
96 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0)); | |
97 | |
98 job_handle = job.Detach(); | |
99 ASSERT_TRUE(job_handle != NULL); | |
100 | |
101 JOBOBJECT_BASIC_UI_RESTRICTIONS jbur = {0}; | |
102 DWORD size = sizeof(jbur); | |
103 BOOL result = ::QueryInformationJobObject(job_handle, | |
104 JobObjectBasicUIRestrictions, | |
105 &jbur, size, &size); | |
106 ASSERT_TRUE(result); | |
107 | |
108 ASSERT_EQ(jbur.UIRestrictionsClass & JOB_OBJECT_UILIMIT_READCLIPBOARD, | |
109 JOB_OBJECT_UILIMIT_READCLIPBOARD); | |
110 ::CloseHandle(job_handle); | |
111 } | |
112 } | |
113 | |
114 // Tests the error case when the job is initialized twice. | |
115 TEST(JobTest, DoubleInit) { | |
116 // Create the job. | |
117 Job job; | |
118 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_LOCKDOWN, L"my_test_job_name", 0)); | |
119 ASSERT_EQ(ERROR_ALREADY_INITIALIZED, job.Init(JOB_LOCKDOWN, L"test", 0)); | |
120 } | |
121 | |
122 // Tests the error case when we use a method and the object is not yet | |
123 // initialized. | |
124 TEST(JobTest, NoInit) { | |
125 Job job; | |
126 ASSERT_EQ(ERROR_NO_DATA, job.UserHandleGrantAccess(NULL)); | |
127 ASSERT_EQ(ERROR_NO_DATA, job.AssignProcessToJob(NULL)); | |
128 ASSERT_TRUE(job.Detach() == NULL); | |
129 } | |
130 | |
131 // Tests the initialization of the job with different security level. | |
132 TEST(JobTest, SecurityLevel) { | |
133 Job job1; | |
134 ASSERT_EQ(ERROR_SUCCESS, job1.Init(JOB_LOCKDOWN, L"job1", 0)); | |
135 | |
136 Job job2; | |
137 ASSERT_EQ(ERROR_SUCCESS, job2.Init(JOB_RESTRICTED, L"job2", 0)); | |
138 | |
139 Job job3; | |
140 ASSERT_EQ(ERROR_SUCCESS, job3.Init(JOB_LIMITED_USER, L"job3", 0)); | |
141 | |
142 Job job4; | |
143 ASSERT_EQ(ERROR_SUCCESS, job4.Init(JOB_INTERACTIVE, L"job4", 0)); | |
144 | |
145 Job job5; | |
146 ASSERT_EQ(ERROR_SUCCESS, job5.Init(JOB_UNPROTECTED, L"job5", 0)); | |
147 | |
148 Job job6; | |
149 ASSERT_EQ(ERROR_BAD_ARGUMENTS, job6.Init( | |
150 static_cast<JobLevel>(JOB_UNPROTECTED+1), L"job6", 0)); | |
151 } | |
152 | |
153 // Tests the method "AssignProcessToJob". | |
154 TEST(JobTest, ProcessInJob) { | |
155 // Create the job. | |
156 Job job; | |
157 ASSERT_EQ(ERROR_SUCCESS, job.Init(JOB_UNPROTECTED, L"job_test_process", 0)); | |
158 | |
159 BOOL result = FALSE; | |
160 | |
161 wchar_t notepad[] = L"notepad"; | |
162 STARTUPINFO si = { sizeof(si) }; | |
163 base::win::ScopedProcessInformation pi; | |
164 result = ::CreateProcess(NULL, notepad, NULL, NULL, FALSE, 0, NULL, NULL, &si, | |
165 pi.Receive()); | |
166 ASSERT_TRUE(result); | |
167 ASSERT_EQ(ERROR_SUCCESS, job.AssignProcessToJob(pi.process_handle())); | |
168 | |
169 // Get the job handle. | |
170 HANDLE job_handle = job.Detach(); | |
171 | |
172 // Check if the process is in the job. | |
173 JOBOBJECT_BASIC_PROCESS_ID_LIST jbpidl = {0}; | |
174 DWORD size = sizeof(jbpidl); | |
175 result = ::QueryInformationJobObject(job_handle, | |
176 JobObjectBasicProcessIdList, | |
177 &jbpidl, size, &size); | |
178 EXPECT_TRUE(result); | |
179 | |
180 EXPECT_EQ(1, jbpidl.NumberOfAssignedProcesses); | |
181 EXPECT_EQ(1, jbpidl.NumberOfProcessIdsInList); | |
182 EXPECT_EQ(pi.process_id(), jbpidl.ProcessIdList[0]); | |
183 | |
184 EXPECT_TRUE(::TerminateProcess(pi.process_handle(), 0)); | |
185 | |
186 EXPECT_TRUE(::CloseHandle(job_handle)); | |
187 } | |
188 | |
189 } // namespace sandbox | |
OLD | NEW |