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

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