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

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: Cleanup 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
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
Mark Mentovai 2012/01/20 20:41:35 No blank line here.
Scott Byer 2012/01/20 23:13:37 Done.
9 #include <sys/socket.h>
10 #include <sys/un.h>
11
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"
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 const size_t kMaxPipeNameLength = 104;
Mark Mentovai 2012/01/20 20:41:35 Rather than hard-coding 104 again here, can you us
Scott Byer 2012/01/20 23:13:37 Done.
26
16 // static 27 // static
17 bool MockLaunchd::MakeABundle(const FilePath& dst, 28 bool MockLaunchd::MakeABundle(const FilePath& dst,
18 const std::string& name, 29 const std::string& name,
19 FilePath* bundle_root, 30 FilePath* bundle_root,
20 FilePath* executable) { 31 FilePath* executable) {
21 *bundle_root = dst.Append(name + std::string(".app")); 32 *bundle_root = dst.Append(name + std::string(".app"));
22 FilePath contents = bundle_root->AppendASCII("Contents"); 33 FilePath contents = bundle_root->AppendASCII("Contents");
23 FilePath mac_os = contents.AppendASCII("MacOS"); 34 FilePath mac_os = contents.AppendASCII("MacOS");
24 *executable = mac_os.Append(name); 35 *executable = mac_os.Append(name);
25 FilePath info_plist = contents.Append("Info.plist"); 36 FilePath info_plist = contents.Append("Info.plist");
26 37
27 if (!file_util::CreateDirectory(mac_os)) { 38 if (!file_util::CreateDirectory(mac_os)) {
28 return false; 39 return false;
29 } 40 }
30 const char *data = "#! testbundle\n"; 41 const char *data = "#! testbundle\n";
31 int len = strlen(data); 42 int len = strlen(data);
32 if (file_util::WriteFile(*executable, data, len) != len) { 43 if (file_util::WriteFile(*executable, data, len) != len) {
33 return false; 44 return false;
34 } 45 }
35 if (chmod(executable->value().c_str(), 0555) != 0) { 46 if (chmod(executable->value().c_str(), 0555) != 0) {
36 return false; 47 return false;
37 } 48 }
38 49
50 chrome::VersionInfo version_info;
51
39 const char* info_plist_format = 52 const char* info_plist_format =
40 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" 53 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
41 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" " 54 "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" "
42 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" 55 "\"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n"
43 "<plist version=\"1.0\">\n" 56 "<plist version=\"1.0\">\n"
44 "<dict>\n" 57 "<dict>\n"
45 " <key>CFBundleDevelopmentRegion</key>\n" 58 " <key>CFBundleDevelopmentRegion</key>\n"
46 " <string>English</string>\n" 59 " <string>English</string>\n"
47 " <key>CFBundleIdentifier</key>\n" 60 " <key>CFBundleIdentifier</key>\n"
48 " <string>com.test.%s</string>\n" 61 " <string>com.test.%s</string>\n"
49 " <key>CFBundleInfoDictionaryVersion</key>\n" 62 " <key>CFBundleInfoDictionaryVersion</key>\n"
50 " <string>6.0</string>\n" 63 " <string>6.0</string>\n"
51 " <key>CFBundleExecutable</key>\n" 64 " <key>CFBundleExecutable</key>\n"
52 " <string>%s</string>\n" 65 " <string>%s</string>\n"
53 " <key>CFBundleVersion</key>\n" 66 " <key>CFBundleVersion</key>\n"
54 " <string>1</string>\n" 67 " <string>1</string>\n"
68 " <key>CFBundleShortVersionString</key>\n"
Mark Mentovai 2012/01/20 20:41:35 The keys in this dict were already sorted, so you
Scott Byer 2012/01/20 23:13:37 They weren't completely, all fixed up. Done.
69 " <string>%s</string>\n"
55 "</dict>\n" 70 "</dict>\n"
56 "</plist>\n"; 71 "</plist>\n";
57 std::string info_plist_data = base::StringPrintf(info_plist_format, 72 std::string info_plist_data =
58 name.c_str(), 73 base::StringPrintf(info_plist_format,
59 name.c_str()); 74 name.c_str(),
75 name.c_str(),
76 version_info.Version().c_str());
60 len = info_plist_data.length(); 77 len = info_plist_data.length();
61 if (file_util::WriteFile(info_plist, info_plist_data.c_str(), len) != len) { 78 if (file_util::WriteFile(info_plist, info_plist_data.c_str(), len) != len) {
62 return false; 79 return false;
63 } 80 }
64 const UInt8* bundle_root_path = 81 const UInt8* bundle_root_path =
65 reinterpret_cast<const UInt8*>(bundle_root->value().c_str()); 82 reinterpret_cast<const UInt8*>(bundle_root->value().c_str());
66 base::mac::ScopedCFTypeRef<CFURLRef> url( 83 base::mac::ScopedCFTypeRef<CFURLRef> url(
67 CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, 84 CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
68 bundle_root_path, 85 bundle_root_path,
69 bundle_root->value().length(), 86 bundle_root->value().length(),
70 true)); 87 true));
71 base::mac::ScopedCFTypeRef<CFBundleRef> bundle( 88 base::mac::ScopedCFTypeRef<CFBundleRef> bundle(
72 CFBundleCreate(kCFAllocatorDefault, url)); 89 CFBundleCreate(kCFAllocatorDefault, url));
73 return bundle.get(); 90 return bundle.get();
74 } 91 }
75 92
93 MockLaunchd::MockLaunchd(const FilePath& file, MessageLoop* loop,
94 bool create_socket, bool as_service)
95 : file_(file),
96 message_loop_(loop),
97 create_socket_(create_socket),
98 as_service_(as_service),
99 restart_called_(false),
100 remove_called_(false),
101 job_called_(false),
102 checkin_called_(false),
103 write_called_(false),
104 delete_called_(false) {
105 std::string pipe_suffix("_SOCKET");
106 FilePath socket_path = file_;
107 while (socket_path.value().length() + pipe_suffix.length() >
Mark Mentovai 2012/01/20 20:41:35 Shouldn’t this be >= or -2? You’ll need to add a s
Scott Byer 2012/01/20 23:13:37 Done.
108 kMaxPipeNameLength - 1)
Mark Mentovai 2012/01/20 20:41:35 Can we use {braces} here for readability because t
Scott Byer 2012/01/20 23:13:37 Done.
109 socket_path = socket_path.DirName();
Mark Mentovai 2012/01/20 20:41:35 I guess this approach is OK for test code. The pat
110 pipe_name_ = socket_path.value() + pipe_suffix;
111 }
112
113 MockLaunchd::~MockLaunchd() {
114 }
115
76 CFDictionaryRef MockLaunchd::CopyExports() { 116 CFDictionaryRef MockLaunchd::CopyExports() {
77 ADD_FAILURE(); 117 if (!create_socket_) {
78 return NULL; 118 ADD_FAILURE();
119 return NULL;
120 }
121
122 CFStringRef env_var =
123 base::mac::NSToCFCast(GetServiceProcessLaunchDSocketEnvVar());
124 CFStringRef socket_path = CFStringCreateWithCString(kCFAllocatorDefault,
Mark Mentovai 2012/01/20 20:41:35 Leaked? Use a ScopedCFTypeRef.
Scott Byer 2012/01/20 23:13:37 Done.
125 pipe_name_.c_str(),
126 kCFStringEncodingUTF8);
127 const void *keys[] = { env_var };
128 const void *values[] = { socket_path };
Mark Mentovai 2012/01/20 20:41:35 You can DCHECK (probably statically, even, a la CO
Scott Byer 2012/01/20 23:13:37 Done.
129 return CFDictionaryCreate(kCFAllocatorDefault,
130 keys,
131 values,
132 arraysize(keys),
133 &kCFTypeDictionaryKeyCallBacks,
134 &kCFTypeDictionaryValueCallBacks);
79 } 135 }
80 136
81 CFDictionaryRef MockLaunchd::CopyJobDictionary(CFStringRef label) { 137 CFDictionaryRef MockLaunchd::CopyJobDictionary(CFStringRef label) {
82 ADD_FAILURE(); 138 if (!as_service_) {
83 return NULL; 139 scoped_ptr<MultiProcessLock> running_lock(
140 TakeNamedLock(pipe_name_, false));
141 if (running_lock.get())
142 return NULL;
143 }
144
145 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM);
146 CFStringRef program_pid = CFSTR(LAUNCH_JOBKEY_PID);
147 const void *keys[] = { program, program_pid };
148 base::mac::ScopedCFTypeRef<CFStringRef> path(
149 base::SysUTF8ToCFStringRef(file_.value()));
150 int process_id = base::GetCurrentProcId();
151 base::mac::ScopedCFTypeRef<CFNumberRef> pid(
152 CFNumberCreate(NULL, kCFNumberIntType, &process_id));
153 const void *values[] = { path, pid };
Mark Mentovai 2012/01/20 20:41:35 Here too? 177 also?
Scott Byer 2012/01/20 23:13:37 Done.
154 return CFDictionaryCreate(kCFAllocatorDefault,
155 keys,
156 values,
157 arraysize(keys),
158 &kCFTypeDictionaryKeyCallBacks,
159 &kCFTypeDictionaryValueCallBacks);
84 } 160 }
85 161
86 CFDictionaryRef MockLaunchd::CopyDictionaryByCheckingIn(CFErrorRef* error) { 162 CFDictionaryRef MockLaunchd::CopyDictionaryByCheckingIn(CFErrorRef* error) {
87 checkin_called_ = true; 163 checkin_called_ = true;
88 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM); 164 CFStringRef program = CFSTR(LAUNCH_JOBKEY_PROGRAM);
89 CFStringRef program_args = CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS); 165 CFStringRef program_args = CFSTR(LAUNCH_JOBKEY_PROGRAMARGUMENTS);
90 const void *keys[] = { program, program_args };
91 base::mac::ScopedCFTypeRef<CFStringRef> path( 166 base::mac::ScopedCFTypeRef<CFStringRef> path(
92 base::SysUTF8ToCFStringRef(file_.value())); 167 base::SysUTF8ToCFStringRef(file_.value()));
93 const void *array_values[] = { path.get() }; 168 const void *array_values[] = { path.get() };
94 base::mac::ScopedCFTypeRef<CFArrayRef> args( 169 base::mac::ScopedCFTypeRef<CFArrayRef> args(
95 CFArrayCreate(kCFAllocatorDefault, 170 CFArrayCreate(kCFAllocatorDefault,
96 array_values, 171 array_values,
97 1, 172 1,
98 &kCFTypeArrayCallBacks)); 173 &kCFTypeArrayCallBacks));
99 const void *values[] = { path, args }; 174
175 if (!create_socket_) {
176 const void *keys[] = { program, program_args };
177 const void *values[] = { path, args };
178 return CFDictionaryCreate(kCFAllocatorDefault,
179 keys,
180 values,
181 arraysize(keys),
182 &kCFTypeDictionaryKeyCallBacks,
183 &kCFTypeDictionaryValueCallBacks);
184 }
185
186 CFStringRef socket_key = CFSTR(LAUNCH_JOBKEY_SOCKETS);
187 int local_pipe = -1;
188 EXPECT_TRUE(as_service_);
189
190 // Create unix_addr structure.
191 struct sockaddr_un unix_addr;
192 memset(&unix_addr, 0, sizeof(unix_addr));
Mark Mentovai 2012/01/20 20:41:35 Or just struct sockaddr_un unix_addr = {0};
Scott Byer 2012/01/20 23:13:37 Done.
193 unix_addr.sun_family = AF_UNIX;
194 int path_len = snprintf(unix_addr.sun_path, kMaxPipeNameLength,
195 "%s", pipe_name_.c_str());
Mark Mentovai 2012/01/20 20:41:35 Don’t use snprintf to null-terminate. You can use
Scott Byer 2012/01/20 23:13:37 Done.
196 DCHECK_EQ(static_cast<int>(pipe_name_.length()), path_len);
197 size_t unix_addr_len = offsetof(struct sockaddr_un,
Mark Mentovai 2012/01/20 20:41:35 I would prefer to hold off on computing this until
Scott Byer 2012/01/20 23:13:37 Moved down to just before use. It's just complicat
198 sun_path) + path_len + 1;
199 unix_addr.sun_len = SUN_LEN(&unix_addr);
200
201 CFSocketSignature signature;
202 signature.protocolFamily = PF_UNIX;
203 signature.socketType = SOCK_STREAM;
204 signature.protocol = 0;
205 signature.address = CFDataCreate(NULL, reinterpret_cast<UInt8*>(&unix_addr),
206 unix_addr_len);
207 CFSocketRef socket =
208 CFSocketCreateWithSocketSignature(NULL, &signature, NULL, NULL, NULL);
Mark Mentovai 2012/01/20 20:41:35 Does this consume the reference to signature.addre
Scott Byer 2012/01/20 23:13:37 It's not spelled out explicitly in the docs, but b
209
210 local_pipe = CFSocketGetNative(socket);
211 EXPECT_NE(-1, local_pipe);
212 if (local_pipe == -1) {
213 if (error)
214 *error = CFErrorCreate(kCFAllocatorDefault, kCFErrorDomainPOSIX,
Mark Mentovai 2012/01/20 20:41:35 {brace me}
Scott Byer 2012/01/20 23:13:37 Done.
215 errno, NULL);
216 return NULL;
217 }
218
219 base::mac::ScopedCFTypeRef<CFNumberRef> socket_fd(
220 CFNumberCreate(NULL, kCFNumberIntType, &local_pipe));
221 const void *socket_array_values[] = { socket_fd };
222 base::mac::ScopedCFTypeRef<CFArrayRef> sockets(
223 CFArrayCreate(kCFAllocatorDefault,
224 socket_array_values,
225 1,
226 &kCFTypeArrayCallBacks));
227 CFStringRef socket_dict_key = CFSTR("ServiceProcessSocket");
228 const void *socket_keys[] = { socket_dict_key };
229 const void *socket_values[] = { sockets };
Mark Mentovai 2012/01/20 20:41:35 arraysizes equal? 238 too?
Scott Byer 2012/01/20 23:13:37 Done.
230 base::mac::ScopedCFTypeRef<CFDictionaryRef> socket_dict(
231 CFDictionaryCreate(kCFAllocatorDefault,
232 socket_keys,
233 socket_values,
234 arraysize(socket_keys),
235 &kCFTypeDictionaryKeyCallBacks,
236 &kCFTypeDictionaryValueCallBacks));
237 const void *keys[] = { program, program_args, socket_key };
238 const void *values[] = { path, args, socket_dict };
100 return CFDictionaryCreate(kCFAllocatorDefault, 239 return CFDictionaryCreate(kCFAllocatorDefault,
101 keys, 240 keys,
102 values, 241 values,
103 arraysize(keys), 242 arraysize(keys),
104 &kCFTypeDictionaryKeyCallBacks, 243 &kCFTypeDictionaryKeyCallBacks,
105 &kCFTypeDictionaryValueCallBacks); 244 &kCFTypeDictionaryValueCallBacks);
106 } 245 }
107 246
108 bool MockLaunchd::RemoveJob(CFStringRef label, CFErrorRef* error) { 247 bool MockLaunchd::RemoveJob(CFStringRef label, CFErrorRef* error) {
109 remove_called_ = true; 248 remove_called_ = true;
(...skipping 26 matching lines...) Expand all
136 write_called_ = true; 275 write_called_ = true;
137 return true; 276 return true;
138 } 277 }
139 278
140 bool MockLaunchd::DeletePlist(Domain domain, 279 bool MockLaunchd::DeletePlist(Domain domain,
141 Type type, 280 Type type,
142 CFStringRef name) { 281 CFStringRef name) {
143 delete_called_ = true; 282 delete_called_ = true;
144 return true; 283 return true;
145 } 284 }
285
286 void MockLaunchd::SignalReady() {
287 ASSERT_TRUE(as_service_);
288 running_lock_.reset(TakeNamedLock(pipe_name_, true));
289 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698