- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / pyautolib / chromoting_helper.py
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 """Chromoting helper to install/uninstall host and replace pref pane."""
6
7 import abc
8 import os
9 import shutil
10 import sys
11 import subprocess
12
13
14 class ChromotingHelper(object):
15   """Chromoting helper base class."""
16   __metaclass__ = abc.ABCMeta
17
18   @abc.abstractmethod
19   def InstallHost(self, bin_dir):
20     """Installs the chromoting host"""
21     return
22
23   @abc.abstractmethod
24   def UninstallHost(self, bin_dir):
25     """Uninstalls the chromoting host"""
26     return
27
28
29 class ChromotingHelperMac(ChromotingHelper):
30   """Chromoting Helper class for Mac.
31
32   Installs/uninstalls host and replace the pref pane for testing purpose.
33   """
34
35   def InstallHost(self, bin_dir):
36     """Installs host on Mac."""
37     assert os.geteuid() == 0, 'Need superuser privileges'
38
39     # Run most of the steps here with login user
40     login_uid = os.getuid()
41     os.seteuid(login_uid)
42
43     # Change the working dir to the dir that has the host zip file
44     current_dir = os.getcwd()
45     pyautolib_dir = os.path.dirname(os.path.abspath(__file__))
46     os.chdir(bin_dir)
47     host_dir = 'remoting-me2me-host-mac'
48     output_dir = os.path.join(host_dir, 'output')
49
50     # Remove remoting-me2me-host-mac dir just in case
51     shutil.rmtree(host_dir, True)
52
53     # Unzip the host archive and prepare the files/dirs
54     subprocess.call('unzip remoting-me2me-host-mac.zip', shell=True)
55     subprocess.call('mkdir ' + output_dir, shell=True)
56
57     # Prepare security identity for code signing purpose
58     os.seteuid(0)
59     key_chain = '/Library/Keychains/ChromotingTest'
60     password = '1111'
61     key = os.path.join(pyautolib_dir, 'chromoting_key.p12')
62     cert = os.path.join(pyautolib_dir, 'chromoting_cert.p12')
63     subprocess.call(['security', 'delete-keychain', key_chain])
64     subprocess.call(['security', 'create-keychain', '-p',
65                      password, key_chain])
66     subprocess.call(['security', 'import', key,
67                      '-k', key_chain, '-P', password, '-A'])
68     subprocess.call(['security', 'import', cert,
69                      '-k', key_chain, '-P', password])
70     os.seteuid(login_uid)
71
72     # Sign the host
73     do_signing = os.path.join(host_dir, 'do_signing.sh')
74     subprocess.call(do_signing + ' ' + output_dir + ' ' + host_dir + ' ' +
75                     key_chain + ' "Chromoting Test"', shell=True)
76
77     # Remove security identify
78     os.seteuid(0)
79     subprocess.call(['security', 'delete-keychain', key_chain])
80     os.seteuid(login_uid)
81
82     # Figure out the dmg name
83     version = ""
84     for output_file in os.listdir(output_dir):
85       if output_file.endswith('.dmg'):
86         version = os.path.basename(output_file)[len('ChromotingHost-'):-4]
87
88     # Mount before installation
89     dmg = os.path.join(output_dir, 'ChromotingHost-' + version + '.dmg')
90     subprocess.call('hdiutil' + ' mount ' + dmg, shell=True)
91
92     # Install host
93     os.seteuid(0)
94     mpkg = os.path.join('/Volumes', 'Chromoting Host ' + version,
95                         'Chromoting Host.pkg')
96     subprocess.call(['/usr/sbin/installer', '-pkg',
97                      mpkg, '-target', '/'])
98     os.seteuid(login_uid)
99
100     # Unmount after installation
101     mounted = os.path.join('/Volumes', 'Chromoting Host ' + version)
102     subprocess.call('hdiutil detach "' + mounted + '"', shell=True)
103
104     # Clean up remoting-me2me-host-mac dir
105     shutil.rmtree(host_dir, True)
106
107     # Resume the original working dir
108     os.chdir(current_dir)
109
110   def UninstallHost(self, bin_dir):
111     """Uninstalls host on Mac."""
112     assert os.geteuid() == 0, 'Need superuser privileges'
113     uninstall_app = os.path.join('/', 'Applications',
114                                  'Chromoting Host Uninstaller.app',
115                                  'Contents', 'MacOS',
116                                  'remoting_host_uninstaller')
117     subprocess.call([uninstall_app, '--no-ui'])
118
119   def ReplacePrefPaneMac(self, operation):
120     """Constructs mock pref pane to replace the actual pref pane on Mac."""
121     assert os.geteuid() == 0, 'Need superuser privileges'
122
123     pref_pane_dir = os.path.join('/Library', 'PreferencePanes')
124
125     mock_pref_pane = os.path.join(pref_pane_dir, 'mock_pref_pane')
126     pref_pane = os.path.join(pref_pane_dir,
127                              'org.chromium.chromoting.prefPane')
128     mock_pref_pane_python = os.path.join(
129         os.path.dirname(os.path.abspath(__file__)),
130         'mock_pref_pane.py')
131
132     # When the symlink from real pref pane to mock pref pane exists,
133     # mock pref pane will be modified to be a dir when the host is installed.
134     # After the host is installed and mock pref pane is modified to be a file,
135     # it will be a file until next host installation.
136     if os.path.isdir(mock_pref_pane):
137       shutil.rmtree(mock_pref_pane, True)
138     elif os.path.isfile(mock_pref_pane):
139       os.remove(mock_pref_pane)
140
141     mock_pref_pane_file = open(mock_pref_pane, 'w')
142     mock_pref_pane_file.write('#!/bin/bash\n')
143     mock_pref_pane_file.write('\n')
144     mock_pref_pane_file.write('suid-python'  +
145                               ' ' + mock_pref_pane_python + ' ' + operation)
146     mock_pref_pane_file.close()
147
148     subprocess.call(['chmod', 'a+x', mock_pref_pane])
149
150     # The real pref pane is a dir if the host is installed on a clean machine.
151     # Once the test is run on the machine, real pref pane will be replaced to
152     # a symlink.
153     if os.path.isdir(pref_pane):
154       shutil.rmtree(pref_pane, True)
155     elif os.path.isfile(pref_pane):
156       os.remove(pref_pane)
157
158     subprocess.call(['ln', '-s', mock_pref_pane, pref_pane])
159
160
161 class ChromotingHelperWindows(ChromotingHelper):
162   """Chromoting Helper class for Windows for installing/uninstalling host."""
163
164   def InstallHost(self, bin_dir):
165     """Installs host on Windows."""
166     host_msi = os.path.join(bin_dir, 'chromoting.msi')
167     subprocess.Popen(['msiexec', '/i', host_msi, '/passive']).wait()
168
169   def UninstallHost(self, bin_dir):
170     """Uninstalls host on Windows."""
171     host_msi = os.path.join(bin_dir, 'chromoting.msi')
172     subprocess.Popen(['msiexec', '/x', host_msi, '/passive']).wait()
173
174
175 def Main():
176   """Main function to dispatch operations."""
177   assert sys.platform.startswith('win') or \
178       sys.platform.startswith('darwin'), \
179       'Only support Windows and Mac'
180
181   if sys.platform.startswith('win'):
182     helper = ChromotingHelperWindows()
183   elif sys.platform.startswith('darwin'):
184     helper = ChromotingHelperMac()
185
186   if sys.argv[1] == 'install':
187     helper.InstallHost(sys.argv[2])
188   elif sys.argv[1] == 'uninstall':
189     helper.UninstallHost(sys.argv[2])
190   elif sys.argv[1] in ['enable', 'disable', 'changepin']:
191     assert sys.platform.startswith('darwin'), \
192       'Replacing pref pane is Mac specific'
193     helper.ReplacePrefPaneMac(sys.argv[1])
194   else:
195     print >>sys.stderr, 'Invalid syntax'
196     return 1
197
198
199 if __name__ == '__main__':
200   Main()