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

Side by Side Diff: chrome/common/mac/mock_launchd.cc

Issue 9131016: Cloud Print Policy - service side enforcement, Mac browser tests. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: address nit + REBASE Created 8 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 | Annotate | Revision Log
« no previous file with comments | « chrome/common/mac/mock_launchd.h ('k') | chrome/common/service_process_util.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/mac/mock_launchd.h" 5 #include "chrome/common/mac/mock_launchd.h"
6 6
7 #include <CoreFoundation/CoreFoundation.h>
8 #include <sys/socket.h>
9 #include <sys/un.h>
10
11 #include "base/basictypes.h"
7 #include "base/file_path.h" 12 #include "base/file_path.h"
8 #include "base/file_util.h" 13 #include "base/file_util.h"
14 #include "base/mac/foundation_util.h"
9 #include "base/mac/scoped_cftyperef.h" 15 #include "base/mac/scoped_cftyperef.h"
10 #include "base/message_loop.h" 16 #include "base/message_loop.h"
17 #include "base/process_util.h"
18 #include "base/string_util.h"
11 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
12 #include "base/sys_string_conversions.h" 20 #include "base/sys_string_conversions.h"
21 #include "chrome/common/chrome_version_info.h"
13 #include "chrome/common/mac/launchd.h" 22 #include "chrome/common/mac/launchd.h"
23 #include "chrome/common/service_process_util.h"
14 #include "testing/gtest/include/gtest/gtest.h" 24 #include "testing/gtest/include/gtest/gtest.h"
15 25
26 static sockaddr_un* throwaway_sockaddr_un;
27 static const size_t kMaxPipeNameLength =
28 sizeof(throwaway_sockaddr_un->sun_path);
29
16 // static 30 // static
17 bool MockLaunchd::MakeABundle(const FilePath& dst, 31 bool MockLaunchd::MakeABundle(const FilePath& dst,
18 const std::string& name, 32 const std::string& name,
19 FilePath* bundle_root, 33 FilePath* bundle_root,
20 FilePath* executable) { 34 FilePath* executable) {
21 *bundle_root = dst.Append(name + std::string(".app")); 35 *bundle_root = dst.Append(name + std::string(".app"));
22 FilePath contents = bundle_root->AppendASCII("Contents"); 36 FilePath contents = bundle_root->AppendASCII("Contents");
23 FilePath mac_os = contents.AppendASCII("MacOS"); 37 FilePath mac_os = contents.AppendASCII("MacOS");
24 *executable = mac_os.Append(name); 38 *executable = mac_os.Append(name);
25 FilePath info_plist = contents.Append("Info.plist"); 39 FilePath info_plist = contents.Append("Info.plist");
26 40
27 if (!file_util::CreateDirectory(mac_os)) { 41 if (!file_util::CreateDirectory(mac_os)) {
28 return false; 42 return false;
29 } 43 }
30 const char *data = "#! testbundle\n"; 44 const char *data = "#! testbundle\n";
31 int len = strlen(data); 45 int len = strlen(data);
32 if (file_util::WriteFile(*executable, data, len) != len) { 46 if (file_util::WriteFile(*executable, data, len) != len) {
33 return false; 47 return false;
34 } 48 }
35 if (chmod(executable->value().c_str(), 0555) != 0) { 49 if (chmod(executable->value().c_str(), 0555) != 0) {
36 return false; 50 return false;
37 } 51 }
38 52
53 chrome::VersionInfo version_info;
54
39 const char* info_plist_format = 55 const char* info_plist_format =
40 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 56 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
41 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " 57 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
42 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 58 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
43 "<plist version=\"1.0\">\n" 59 "<plist version=\"1.0\">\n"
44 "<dict>\n" 60 "<dict>\n"
45 " <key>CFBundleDevelopmentRegion</key>\n" 61 " <key>CFBundleDevelopmentRegion</key>\n"
46 " <string>English</string>\n" 62 " <string>English</string>\n"
63 " <key>CFBundleExecutable</key>\n"
64 " <string>%s</string>\n"
47 " <key>CFBundleIdentifier</key>\n" 65 " <key>CFBundleIdentifier</key>\n"
48 " <string>com.test.%s</string>\n" 66 " <string>com.test.%s</string>\n"
49 " <key>CFBundleInfoDictionaryVersion</key>\n" 67 " <key>CFBundleInfoDictionaryVersion</key>\n"
50 " <string>6.0</string>\n" 68 " <string>6.0</string>\n"
51 " <key>CFBundleExecutable</key>\n" 69 " <key>CFBundleShortVersionString</key>\n"
52 " <string>%s</string>\n" 70 " <string>%s</string>\n"
53 " <key>CFBundleVersion</key>\n" 71 " <key>CFBundleVersion</key>\n"
54 " <string>1</string>\n" 72 " <string>1</string>\n"
55 "</dict>\n" 73 "</dict>\n"
56 "</plist>\n"; 74 "</plist>\n";
57 std::string info_plist_data = base::StringPrintf(info_plist_format, 75 std::string info_plist_data =
58 name.c_str(), 76 base::StringPrintf(info_plist_format,
59 name.c_str()); 77 name.c_str(),
78 name.c_str(),
79 version_info.Version().c_str());
60 len = info_plist_data.length(); 80 len = info_plist_data.length();
61 if (file_util::WriteFile(info_plist, info_plist_data.c_str(), len) != len) { 81 if (file_util::WriteFile(info_plist, info_plist_data.c_str(), len) != len) {
62 return false; 82 return false;
63 } 83 }
64 const UInt8* bundle_root_path = 84 const UInt8* bundle_root_path =
65 reinterpret_cast<const UInt8*>(bundle_root->value().c_str()); 85 reinterpret_cast<const UInt8*>(bundle_root->value().c_str());
66 base::mac::ScopedCFTypeRef<CFURLRef> url( 86 base::mac::ScopedCFTypeRef<CFURLRef> url(
67 CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, 87 CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
68 bundle_root_path, 88 bundle_root_path,
69 bundle_root->value().length(), 89 bundle_root->value().length(),
70 true)); 90 true));
71 base::mac::ScopedCFTypeRef<CFBundleRef> bundle( 91 base::mac::ScopedCFTypeRef<CFBundleRef> bundle(
72 CFBundleCreate(kCFAllocatorDefault, url)); 92 CFBundleCreate(kCFAllocatorDefault, url));
73 return bundle.get(); 93 return bundle.get();
74 } 94 }
75 95
96 MockLaunchd::MockLaunchd(const FilePath& file, MessageLoop* loop,
97 bool create_socket, bool as_service)
98 : file_(file),
99 message_loop_(loop),
100 create_socket_(create_socket),
101 as_service_(as_service),
102 restart_called_(false),
103 remove_called_(false),
104 job_called_(false),
105 checkin_called_(false),
106 write_called_(false),
107 delete_called_(false) {
108 std::string pipe_suffix("_SOCKET");
109 FilePath socket_path = file_;
110 while (socket_path.value().length() + pipe_suffix.length() >
111 kMaxPipeNameLength - 2) {
112 socket_path = socket_path.DirName();
113 }
114 pipe_name_ = socket_path.value() + pipe_suffix;
115 }
116
117 MockLaunchd::~MockLaunchd() {
118 }
119
76 CFDictionaryRef MockLaunchd::CopyExports() { 120 CFDictionaryRef MockLaunchd::CopyExports() {
77 ADD_FAILURE(); 121 if (!create_socket_) {
78 return NULL; 122 ADD_FAILURE();
123 return NULL;
124 }
125
126 CFStringRef env_var =
127 base::mac::NSToCFCast(GetServiceProcessLaunchDSocketEnvVar());
128 base::mac::ScopedCFTypeRef<CFStringRef> socket_path(
129 CFStringCreateWithCString(kCFAllocatorDefault, pipe_name_.c_str(),
130 kCFStringEncodingUTF8));
131 const void *keys[] = { env_var };
132 const void *values[] = { socket_path };
133 COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match);
134 return CFDictionaryCreate(kCFAllocatorDefault,
135 keys,
136 values,
137 arraysize(keys),
138 &kCFTypeDictionaryKeyCallBacks,
139 &kCFTypeDictionaryValueCallBacks);
79 } 140 }
80 141
81 CFDictionaryRef MockLaunchd::CopyJobDictionary(CFStringRef label) { 142 CFDictionaryRef MockLaunchd::CopyJobDictionary(CFStringRef label) {
82 ADD_FAILURE(); 143 if (!as_service_) {
83 return NULL; 144 scoped_ptr<MultiProcessLock> running_lock(
145 TakeNamedLock(pipe_name_, false));
146 if (running_lock.get())
147 return NULL;
148 }
149
150 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM);
151 CFStringRef program_pid = CFSTR(LAUNCH_JOBKEY_PID);
152 const void *keys[] = { program, program_pid };
153 base::mac::ScopedCFTypeRef<CFStringRef> path(
154 base::SysUTF8ToCFStringRef(file_.value()));
155 int process_id = base::GetCurrentProcId();
156 base::mac::ScopedCFTypeRef<CFNumberRef> pid(
157 CFNumberCreate(NULL, kCFNumberIntType, &process_id));
158 const void *values[] = { path, pid };
159 COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match);
160 return CFDictionaryCreate(kCFAllocatorDefault,
161 keys,
162 values,
163 arraysize(keys),
164 &kCFTypeDictionaryKeyCallBacks,
165 &kCFTypeDictionaryValueCallBacks);
84 } 166 }
85 167
86 CFDictionaryRef MockLaunchd::CopyDictionaryByCheckingIn(CFErrorRef* error) { 168 CFDictionaryRef MockLaunchd::CopyDictionaryByCheckingIn(CFErrorRef* error) {
87 checkin_called_ = true; 169 checkin_called_ = true;
88 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM); 170 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM);
89 CFStringRef program_args = CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS); 171 CFStringRef program_args = CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS);
90 const void *keys[] = { program, program_args };
91 base::mac::ScopedCFTypeRef<CFStringRef> path( 172 base::mac::ScopedCFTypeRef<CFStringRef> path(
92 base::SysUTF8ToCFStringRef(file_.value())); 173 base::SysUTF8ToCFStringRef(file_.value()));
93 const void *array_values[] = { path.get() }; 174 const void *array_values[] = { path.get() };
94 base::mac::ScopedCFTypeRef<CFArrayRef> args( 175 base::mac::ScopedCFTypeRef<CFArrayRef> args(
95 CFArrayCreate(kCFAllocatorDefault, 176 CFArrayCreate(kCFAllocatorDefault,
96 array_values, 177 array_values,
97 1, 178 1,
98 &kCFTypeArrayCallBacks)); 179 &kCFTypeArrayCallBacks));
99 const void *values[] = { path, args }; 180
181 if (!create_socket_) {
182 const void *keys[] = { program, program_args };
183 const void *values[] = { path, args };
184 COMPILE_ASSERT(arraysize(keys) == arraysize(values),
185 array_sizes_must_match);
186 return CFDictionaryCreate(kCFAllocatorDefault,
187 keys,
188 values,
189 arraysize(keys),
190 &kCFTypeDictionaryKeyCallBacks,
191 &kCFTypeDictionaryValueCallBacks);
192 }
193
194 CFStringRef socket_key = CFSTR(LAUNCH_JOBKEY_SOCKETS);
195 int local_pipe = -1;
196 EXPECT_TRUE(as_service_);
197
198 // Create unix_addr structure.
199 struct sockaddr_un unix_addr = {0};
200 unix_addr.sun_family = AF_UNIX;
201 size_t path_len =
202 base::strlcpy(unix_addr.sun_path, pipe_name_.c_str(), kMaxPipeNameLength);
203 DCHECK_EQ(pipe_name_.length(), path_len);
204 unix_addr.sun_len = SUN_LEN(&unix_addr);
205
206 CFSocketSignature signature;
207 signature.protocolFamily = PF_UNIX;
208 signature.socketType = SOCK_STREAM;
209 signature.protocol = 0;
210 size_t unix_addr_len = offsetof(struct sockaddr_un,
211 sun_path) + path_len + 1;
212 base::mac::ScopedCFTypeRef<CFDataRef> address(
213 CFDataCreate(NULL, reinterpret_cast<UInt8*>(&unix_addr), unix_addr_len));
214 signature.address = address;
215
216 CFSocketRef socket =
217 CFSocketCreateWithSocketSignature(NULL, &signature, NULL, NULL, NULL);
218
219 local_pipe = CFSocketGetNative(socket);
220 EXPECT_NE(-1, local_pipe);
221 if (local_pipe == -1) {
222 if (error) {
223 *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX,
224 errno, NULL);
225 }
226 return NULL;
227 }
228
229 base::mac::ScopedCFTypeRef<CFNumberRef> socket_fd(
230 CFNumberCreate(NULL, kCFNumberIntType, &local_pipe));
231 const void *socket_array_values[] = { socket_fd };
232 base::mac::ScopedCFTypeRef<CFArrayRef> sockets(
233 CFArrayCreate(kCFAllocatorDefault,
234 socket_array_values,
235 1,
236 &kCFTypeArrayCallBacks));
237 CFStringRef socket_dict_key = CFSTR("ServiceProcessSocket");
238 const void *socket_keys[] = { socket_dict_key };
239 const void *socket_values[] = { sockets };
240 COMPILE_ASSERT(arraysize(socket_keys) == arraysize(socket_values),
241 socket_array_sizes_must_match);
242 base::mac::ScopedCFTypeRef<CFDictionaryRef> socket_dict(
243 CFDictionaryCreate(kCFAllocatorDefault,
244 socket_keys,
245 socket_values,
246 arraysize(socket_keys),
247 &kCFTypeDictionaryKeyCallBacks,
248 &kCFTypeDictionaryValueCallBacks));
249 const void *keys[] = { program, program_args, socket_key };
250 const void *values[] = { path, args, socket_dict };
251 COMPILE_ASSERT(arraysize(keys) == arraysize(values), array_sizes_must_match);
100 return CFDictionaryCreate(kCFAllocatorDefault, 252 return CFDictionaryCreate(kCFAllocatorDefault,
101 keys, 253 keys,
102 values, 254 values,
103 arraysize(keys), 255 arraysize(keys),
104 &kCFTypeDictionaryKeyCallBacks, 256 &kCFTypeDictionaryKeyCallBacks,
105 &kCFTypeDictionaryValueCallBacks); 257 &kCFTypeDictionaryValueCallBacks);
106 } 258 }
107 259
108 bool MockLaunchd::RemoveJob(CFStringRef label, CFErrorRef* error) { 260 bool MockLaunchd::RemoveJob(CFStringRef label, CFErrorRef* error) {
109 remove_called_ = true; 261 remove_called_ = true;
(...skipping 26 matching lines...) Expand all
136 write_called_ = true; 288 write_called_ = true;
137 return true; 289 return true;
138 } 290 }
139 291
140 bool MockLaunchd::DeletePlist(Domain domain, 292 bool MockLaunchd::DeletePlist(Domain domain,
141 Type type, 293 Type type,
142 CFStringRef name) { 294 CFStringRef name) {
143 delete_called_ = true; 295 delete_called_ = true;
144 return true; 296 return true;
145 } 297 }
298
299 void MockLaunchd::SignalReady() {
300 ASSERT_TRUE(as_service_);
301 running_lock_.reset(TakeNamedLock(pipe_name_, true));
302 }
OLDNEW
« no previous file with comments | « chrome/common/mac/mock_launchd.h ('k') | chrome/common/service_process_util.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698