1 // Copyright 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.
7 #include "base/mac/foundation_util.h"
8 #include "base/mac/launchd.h"
9 #include "base/mac/scoped_nsobject.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/time/time.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/google_toolbox_for_mac/src/Foundation/GTMServiceManagement.h"
17 // Returns the parameters needed to launch a really simple script from launchd.
18 NSDictionary* TestJobDictionary(NSString* label_ns) {
19 NSString* shell_script_ns = @"sleep 10; echo TestGTMSMJobSubmitRemove";
20 base::scoped_nsobject<NSMutableArray> job_arguments(
21 [[NSMutableArray alloc] init]);
22 [job_arguments addObject:@"/bin/sh"];
23 [job_arguments addObject:@"-c"];
24 [job_arguments addObject:shell_script_ns];
26 NSMutableDictionary* job_dictionary_ns = [NSMutableDictionary dictionary];
27 [job_dictionary_ns setObject:label_ns forKey:@LAUNCH_JOBKEY_LABEL];
28 [job_dictionary_ns setObject:[NSNumber numberWithBool:YES]
29 forKey:@LAUNCH_JOBKEY_RUNATLOAD];
30 [job_dictionary_ns setObject:job_arguments
31 forKey:@LAUNCH_JOBKEY_PROGRAMARGUMENTS];
32 return job_dictionary_ns;
37 TEST(ServiceProcessControlMac, TestGTMSMJobSubmitRemove) {
38 NSString* label_ns = @"com.chromium.ServiceProcessStateFileManipulationTest";
39 std::string label(label_ns.UTF8String);
40 CFStringRef label_cf = base::mac::NSToCFCast(label_ns);
42 // If the job is loaded or running, remove it.
43 pid_t pid = base::mac::PIDForJob(label);
44 CFErrorRef error = NULL;
46 ASSERT_TRUE(GTMSMJobRemove(label_cf, &error));
48 // The job should not be loaded or running.
49 pid = base::mac::PIDForJob(label);
53 NSDictionary* job_dictionary_ns = TestJobDictionary(label_ns);
54 CFDictionaryRef job_dictionary_cf = base::mac::NSToCFCast(job_dictionary_ns);
55 ASSERT_TRUE(GTMSMJobSubmit(job_dictionary_cf, &error));
57 // The new job should be running.
58 pid = base::mac::PIDForJob(label);
62 ASSERT_TRUE(GTMSMJobRemove(label_cf, &error));
64 // Wait for the job to be killed.
65 base::TimeDelta timeout_in_ms = TestTimeouts::action_timeout();
66 base::Time start_time = base::Time::Now();
68 pid = base::mac::PIDForJob(label);
72 base::Time current_time = base::Time::Now();
73 if (current_time - start_time > timeout_in_ms)
79 // Attempting to remove the job again should fail.
80 EXPECT_FALSE(GTMSMJobRemove(label_cf, &error));