1e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport grp
2e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport mock_flimflam
3e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport os
4e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport pwd
5e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport stat
6e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport time
7e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartimport utils
8e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
9e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartfrom autotest_lib.client.bin import test
10e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartfrom autotest_lib.client.common_lib import error
11e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
12e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewartclass network_ShillInitScripts(test.test):
13e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    """ Test that shill init scripts perform as expected.  Use the
14e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        real filesystem (doing a best effort to archive and restore
15e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        current state).  The shill manager is stopped and a proxy
16e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        DBus entity is installed to accept DBus messages that are sent
17e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        via "dbus-send" in the shill startup scripts.  However, the
18e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        "real" shill is still also started from time to time and we
19e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        check that it is run with the right command line arguments.
20e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    """
21e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    version = 1
22e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    save_directories = [ '/var/cache/shill',
23e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                         '/var/cache/flimflam',
24898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger                         '/run/shill',
25898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger                         '/run/state/logged-in',
26898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger                         '/run/dhcpcd',
27e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                         '/var/lib/dhcpcd',
28e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                         '/home/chronos/.disable_shill' ]
29e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    fake_user = 'not-a-real-user@chromium.org'
30e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    saved_config = '/tmp/network_ShillInitScripts_saved_config.tgz'
31e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    cryptohome_path_command = 'cryptohome-path'
32898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger    guest_shill_user_profile_dir = '/run/shill/guest_user_profile/shill'
33898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger    guest_shill_user_log_dir = '/run/shill/guest_user_profile/shill_logs'
34e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    magic_header = '# --- shill init file test magic header ---'
35e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
36e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
37e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def start_shill(self):
38e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Starts a shill instance. """
39aa401d354435497a4195efad12c89912d5028187Sabin Floares        utils.start_service('shill')
40e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
41e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
42e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def stop_shill(self):
43e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Halt the running shill instance. """
44aa401d354435497a4195efad12c89912d5028187Sabin Floares        utils.stop_service('shill', ignore_status=True)
45e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
46e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        for attempt in range(10):
47e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            if not self.find_pid('shill'):
48e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                break
49e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            time.sleep(1)
50e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        else:
512e7c4826bb98e160d8228892c2bf28e8b26d3f72mukesh agrawal            raise error.TestFail('Shill process does not appear to be dying')
52e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
53e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
549f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart    def login(self, user=None):
55e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Simulate the login process.
56e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
57e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Note: "start" blocks until the "script" block completes.
58e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
59e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param user string user name (email address) to log in.
60e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
61e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
62aa401d354435497a4195efad12c89912d5028187Sabin Floares
63aa401d354435497a4195efad12c89912d5028187Sabin Floares        if utils.has_systemd():
64aa401d354435497a4195efad12c89912d5028187Sabin Floares            start_cmd = (('systemctl set-environment CHROMEOS_USER=%s'
65aa401d354435497a4195efad12c89912d5028187Sabin Floares                          ' && systemctl start shill-start-user-session') %
66aa401d354435497a4195efad12c89912d5028187Sabin Floares                         (user or self.fake_user))
67aa401d354435497a4195efad12c89912d5028187Sabin Floares        else:
68aa401d354435497a4195efad12c89912d5028187Sabin Floares            start_cmd = ('start shill-start-user-session CHROMEOS_USER=%s' %
69aa401d354435497a4195efad12c89912d5028187Sabin Floares                         (user or self.fake_user))
70aa401d354435497a4195efad12c89912d5028187Sabin Floares        utils.system(start_cmd)
719f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart
72e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
739f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart    def login_guest(self):
74e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Simulate guest login.
75e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
76e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        For guest login, session-manager passes an empty CHROMEOS_USER arg.
77e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
78e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
799f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.login('""')
80e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
81e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
82e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def logout(self):
83e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Simulate user logout.
84e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
85e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Note: "start" blocks until the "script" block completes.
86e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
87e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
88aa401d354435497a4195efad12c89912d5028187Sabin Floares        utils.start_service('shill-stop-user-session')
89e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
90e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
91e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def start_test(self):
92e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Setup the start of the test.  Stop shill and create test harness."""
935492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        # Stop a system process on test duts for keeping connectivity up.
94aa401d354435497a4195efad12c89912d5028187Sabin Floares        ret = utils.stop_service('recover_duts', ignore_status=True)
955492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        self.recover_duts_stopped = (ret == 0);
965492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart
97e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.stop_shill()
98e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
995d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        # Deduce the root cryptohome directory name for our fake user.
1005d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.root_cryptohome_dir = utils.system_output(
101e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            '%s system %s' % (self.cryptohome_path_command, self.fake_user))
102e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
1035d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        # Deduce the user cryptohome directory name for our fake user.
1045d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.user_cryptohome_dir = utils.system_output(
1055d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart            '%s user %s' % (self.cryptohome_path_command, self.fake_user))
1065d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart
107069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        # Deduce the directory for memory log storage.
108069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        self.user_cryptohome_log_dir = ('%s/shill_logs' %
109069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                                        self.root_cryptohome_dir)
110069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley
111865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        # The sanitized hash of the username is the basename of the cryptohome.
112865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.fake_user_hash = os.path.basename(self.root_cryptohome_dir)
113865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart
1145d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        # Just in case this hash actually exists, add these to the list of
115e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # saved directories.
1165d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.save_directories.append(self.root_cryptohome_dir)
1175d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.save_directories.append(self.user_cryptohome_dir)
118e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
119e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # Archive the system state we will be modifying, then remove them.
120e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        utils.system('tar zcvf %s --directory / --ignore-failed-read %s'
121e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                     ' 2>/dev/null' %
122e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                     (self.saved_config, ' '.join(self.save_directories)))
123e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        utils.system('rm -rf %s' % ' '.join(self.save_directories),
124e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                     ignore_status=True)
125e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
126e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # Create the fake user's system cryptohome directory.
1275d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.root_cryptohome_dir)
1285d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.new_shill_user_profile_dir = ('%s/shill' %
1295d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                           self.root_cryptohome_dir)
130e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.new_shill_user_profile = ('%s/shill.profile' %
131e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                                       self.new_shill_user_profile_dir)
132e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
1335d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        # Create the fake user's user cryptohome directory.
1345d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.user_cryptohome_dir)
1355d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.flimflam_user_profile_dir = ('%s/flimflam' %
1365d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                          self.user_cryptohome_dir)
1375d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.flimflam_user_profile = ('%s/flimflam.profile' %
1385d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                      self.flimflam_user_profile_dir)
1395d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.old_shill_user_profile_dir = ('%s/shill' %
1405d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                           self.user_cryptohome_dir)
1415d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.old_shill_user_profile = ('%s/shill.profile' %
1425d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                       self.old_shill_user_profile_dir)
143f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        self.mock_flimflam = None
1445d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart
145f0b12b51535f88f3569180e008e82e7418684913Paul Stewart
146f0b12b51535f88f3569180e008e82e7418684913Paul Stewart    def start_mock_flimflam(self):
147f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        """ Start a mock flimflam instance to accept and log DBus calls. """
148e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.mock_flimflam = mock_flimflam.MockFlimflam()
149e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.mock_flimflam.start()
150e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
151e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
152e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def erase_state(self):
153e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Remove all the test harness files. """
154e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        utils.system('rm -rf %s' % ' '.join(self.save_directories))
1555d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.root_cryptohome_dir)
1565d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.user_cryptohome_dir)
157e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
158e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
159e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def end_test(self):
160e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Perform cleanup at the end of the test. """
161f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        if self.mock_flimflam:
162f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            self.mock_flimflam.quit()
163f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            self.mock_flimflam.join()
164e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.erase_state()
165e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        utils.system('tar zxvf %s --directory /' % self.saved_config)
166e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        utils.system('rm -f %s' % self.saved_config)
1675492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        self.restart_system_processes()
1685492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart
1695492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart
1705492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart    def restart_system_processes(self):
1715492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        """ Restart vital system services at the end of the test. """
172aa401d354435497a4195efad12c89912d5028187Sabin Floares        utils.start_service('shill', ignore_status=True)
1735492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        if self.recover_duts_stopped:
174aa401d354435497a4195efad12c89912d5028187Sabin Floares            utils.start_service('recover_duts', ignore_status=True)
175e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
176e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
177e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def assure(self, must_be_true, assertion_name):
178e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Perform a named assertion.
179e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
180e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param must_be_true boolean parameter that must be true.
181e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param assertion_name string name of this assertion.
182e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
183e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
184e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        if not must_be_true:
1855d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart            raise error.TestFail('%s: Assertion failed: %s' %
1865d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart                                 (self.test_name, assertion_name))
187e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
188e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
189e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def assure_path_owner(self, path, owner):
190e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| is owned by |owner|.
191e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
192e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
193e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param owner string user name that should own |path|.
194e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
195e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
196e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(pwd.getpwuid(os.stat(path).st_uid)[0] == owner,
197e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Path %s is owned by %s' % (path, owner))
198e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
199e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
200e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def assure_path_group(self, path, group):
201e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| is owned by |group|.
202e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
203e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
204e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param group string group name that should own |path|.
205e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
206e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
207e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(grp.getgrgid(os.stat(path).st_gid)[0] == group,
208e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Path %s is group-owned by %s' % (path, group))
209e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
210e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
211e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart    def assure_exists(self, path, path_friendly_name):
212e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| exists.
213e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
214e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
215e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path_friendly_name string user-parsable description of |path|.
216e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
217e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
218e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        self.assure(os.path.exists(path), '%s exists' % path_friendly_name)
219e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
220e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
221e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart    def assure_is_dir(self, path, path_friendly_name):
222e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| is a directory.
223e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
224e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
225e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path_friendly_name string user-parsable description of |path|.
226e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
227e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
228e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        self.assure_exists(path, path_friendly_name)
229e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(stat.S_ISDIR(os.lstat(path).st_mode),
230e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart                    '%s is a directory' % path_friendly_name)
231e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
232e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
233e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart    def assure_is_link(self, path, path_friendly_name):
234e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| is a symbolic link.
235e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
236e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
237e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path_friendly_name string user-parsable description of |path|.
238e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
239e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
240e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        self.assure_exists(path, path_friendly_name)
241e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(stat.S_ISLNK(os.lstat(path).st_mode),
242e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart                    '%s is a symbolic link' % path_friendly_name)
243e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
244e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
245e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart    def assure_is_link_to(self, path, pointee, path_friendly_name):
246e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |path| is a symbolic link to |pointee|.
247e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
248e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname to test.
249e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param pointee string pathname that |path| should point to.
250e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path_friendly_name string user-parsable description of |path|.
251e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
252e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
253e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        self.assure_is_link(path, path_friendly_name)
254e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        self.assure(os.readlink(path) == pointee,
255e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart                    '%s is a symbolic link to %s' %
256e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart                    (path_friendly_name, pointee))
257e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
258e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
259e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def assure_method_calls(self, expected_method_calls, assertion_name):
260e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Assert that |expected_method_calls| were executed on mock_flimflam.
261e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
262e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param expected_method_calls list of string-tuple pairs of method
263e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart            name + tuple of arguments.
264e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param assertion_name string name to assign to the assertion.
265e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
266e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
267e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        method_calls = self.mock_flimflam.get_method_calls()
268e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        if len(expected_method_calls) != len(method_calls):
269c1127ce2c01efb763bb7f64cbe255871239c7235Paul Stewart            self.assure(False, '%s: method call count does not match' %
270e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        assertion_name)
271e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        for expected, actual in zip(expected_method_calls, method_calls):
272e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.assure(actual.method == expected[0],
273e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        '%s: method %s matches expected %s' %
274e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        (assertion_name, actual.method, expected[0]))
275e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.assure(actual.argument == expected[1],
276e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        '%s: argument %s matches expected %s' %
277e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        (assertion_name, actual.argument, expected[1]))
278e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
279e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
280e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def create_file_with_contents(self, filename, contents):
281e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a file named |filename| that contains |contents|.
282e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
283e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param filename string name of file.
284e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param contents string contents of file.
285e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
286e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
287e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        with open(filename, 'w') as f:
288e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart            f.write(contents)
289e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
290e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
291e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def touch(self, filename):
292e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create an empty file named |filename|.
293e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
294e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param filename string name of file.
295e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
296e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
297e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(filename, '')
298e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
299e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
300e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def create_new_shill_user_profile(self, contents):
301e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a fake new user profile with |contents|.
302e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
303e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param contents string contents of the new user profile.
304e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
305e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
306e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mkdir(self.new_shill_user_profile_dir)
307e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(self.new_shill_user_profile, contents)
308e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
309e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
310e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def create_old_shill_user_profile(self, contents):
311e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a fake old-style user profile with |contents|.
312e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
313e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param contents string contents of the old user profile.
314e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
315e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
3165d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.old_shill_user_profile_dir)
317e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(self.old_shill_user_profile, contents)
318e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
319e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
320e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def create_flimflam_user_profile(self, contents):
321e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a legacy flimflam user profile with |contents|.
322e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
323e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param contents string contents of the flimflam user profile.
324e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
325e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
3265d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        os.mkdir(self.flimflam_user_profile_dir)
327e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(self.flimflam_user_profile, contents)
328e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
329e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
330e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def file_contents(self, filename):
331e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Returns the contents of |filename|.
332e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
333e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param filename string name of file to read.
334e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
335e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
336e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        with open(filename) as f:
337e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart            return f.read()
338e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
339e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
340e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def find_pid(self, process_name):
341e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Returns the process id of |process_name|.
342e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
343e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param process_name string name of process to search for.
344e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
345e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
346e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        return utils.system_output('pgrep %s' % process_name,
3472e7c4826bb98e160d8228892c2bf28e8b26d3f72mukesh agrawal                                   ignore_status=True).split('\n')[0]
348e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
349e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
350e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def get_commandline(self):
351e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Returns the command line of the current shill executable. """
3522e7c4826bb98e160d8228892c2bf28e8b26d3f72mukesh agrawal        pid = self.find_pid('shill')
353e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        return file('/proc/%s/cmdline' % pid).read().split('\0')
354e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
355e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
356e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def run_once(self):
357e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Main test loop. """
3585492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        try:
3595492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart            self.start_test()
3605492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart        except:
3615492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart            self.restart_system_processes()
3625492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart            raise
3635492b4d0f2acc937d641e7479282af63e2db5bf0Paul Stewart
364e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        try:
365f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            self.run_tests([
366f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_start_shill,
367f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_start_logged_in,
368f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_start_port_flimflam_profile])
369f0b12b51535f88f3569180e008e82e7418684913Paul Stewart
370f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            # The tests above run a real instance of shill, whereas the tests
371f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            # below rely on a mock instance of shill.  We must take care not
372f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            # to run the mock at the same time as a real shill instance.
373f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            self.start_mock_flimflam()
374f0b12b51535f88f3569180e008e82e7418684913Paul Stewart
375f0b12b51535f88f3569180e008e82e7418684913Paul Stewart            self.run_tests([
376f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login,
377f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_guest,
378f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_profile_exists,
379f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_old_shill_profile,
380f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_invalid_old_shill_profile,
381f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_ignore_old_shill_profile,
382f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_flimflam_profile,
383f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_ignore_flimflam_profile,
384f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_prefer_old_shill_profile,
385f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_login_multi_profile,
386f0b12b51535f88f3569180e008e82e7418684913Paul Stewart                self.test_logout])
387e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        finally:
388e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            # Stop any shill instances started during testing.
389e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.stop_shill()
390e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.end_test()
391e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
392e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
393f0b12b51535f88f3569180e008e82e7418684913Paul Stewart    def run_tests(self, tests):
394f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        """ Executes each of the test subparts in sequence.
395f0b12b51535f88f3569180e008e82e7418684913Paul Stewart
396f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        @param tests list of methods to run.
397f0b12b51535f88f3569180e008e82e7418684913Paul Stewart
398f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        """
399f0b12b51535f88f3569180e008e82e7418684913Paul Stewart        for test in tests:
4005d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart          self.test_name = test.__name__
401e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart          test()
402e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart          self.stop_shill()
403e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart          self.erase_state()
404e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
405e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
406e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_start_shill(self):
407e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test all created pathnames during shill startup.
408e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
409e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Also ensure the push argument is not provided by default.
410e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
411e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
412e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.touch('/home/chronos/.disable_shill')
413e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.start_shill()
414898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_dir('/run/shill', 'Shill run directory')
415e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_is_dir('/var/lib/dhcpcd', 'dhcpcd lib directory')
416e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_path_owner('/var/lib/dhcpcd', 'dhcp')
417e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_path_group('/var/lib/dhcpcd', 'dhcp')
418898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_dir('/run/dhcpcd', 'dhcpcd run directory')
419898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_path_owner('/run/dhcpcd', 'dhcp')
420898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_path_group('/run/dhcpcd', 'dhcp')
421e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists('/home/chronos/.disable_shill'),
422e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill disable file does not exist')
423e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure('--push=~chronos/shill' not in self.get_commandline(),
424e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill command line does not contain push argument')
425e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
426e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
427e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_start_logged_in(self):
428e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Tests starting up shill while a user is already logged in.
429e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
430e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        The "--push" argument should not be added even though shill is started
431e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        while a user is logged in.
432e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
433e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
434898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
435898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill/user_profiles')
436f2d52f19e042df144e7d53431fb5fe7d3888ec67Paul Stewart        self.create_new_shill_user_profile('')
437f2d52f19e042df144e7d53431fb5fe7d3888ec67Paul Stewart        os.symlink(self.new_shill_user_profile_dir,
438898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger                   '/run/shill/user_profiles/chronos')
439898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.touch('/run/state/logged-in')
440e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.start_shill()
441ab935fa788603ab7423974c0a8ca8353238a9c89Paul Stewart        self.assure('--push=~chronos/shill' not in self.get_commandline(),
442ab935fa788603ab7423974c0a8ca8353238a9c89Paul Stewart                    'Shill command line does not contain push argument')
443898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.unlink('/run/state/logged-in')
444e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
445e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
446e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_start_port_flimflam_profile(self):
447e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test that we can port a flimflam profile to a new shill profile.
448e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
449e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Startup should move an old flimflam profile into place if a shill
450e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        profile does not already exist.
451e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
452e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
453e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mkdir('/var/cache/flimflam')
454e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        flimflam_profile = '/var/cache/flimflam/default.profile'
455e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(flimflam_profile, self.magic_header)
456e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        shill_profile = '/var/cache/shill/default.profile'
457e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.start_shill()
458e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(flimflam_profile),
459e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam profile no longer exists')
460e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(os.path.exists(shill_profile),
461e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill profile exists')
462e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header in self.file_contents(shill_profile),
463e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill default profile contains our magic header')
464e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
465e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
466e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_start_ignore_flimflam_profile(self):
467e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test that we ignore a flimflam profile if a new profile exists.
468e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
469e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Startup should ignore an old flimflam profile if a shill profile
470e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        already exists.
471e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
472e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
473e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mkdir('/var/cache/flimflam')
474e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mkdir('/var/cache/shill')
475e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        flimflam_profile = '/var/cache/flimflam/default.profile'
476e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_file_with_contents(flimflam_profile, self.magic_header)
477e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        shill_profile = '/var/cache/shill/default.profile'
478e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.touch(shill_profile)
479e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.start_shill()
480e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(os.path.exists(flimflam_profile),
481e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam profile still exists')
482e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header not in self.file_contents(shill_profile),
483e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill default profile does not contain our magic header')
484e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
485e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
486e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login(self):
487e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test the login process.
488e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
489e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login should create a profile directory, then create and push
490e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        a user profile, given no previous state.
491e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
492e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
493898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
494e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
495e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.flimflam_user_profile),
496e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam user profile does not exist')
497e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.old_shill_user_profile),
498e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Old shill user profile does not exist')
499e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.new_shill_user_profile),
500e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'New shill user profile does not exist')
501e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # The DBus "CreateProfile" method should have been handled
502e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # by our mock_flimflam instance, so the profile directory
503e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        # should not have actually been created.
504e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_is_dir(self.new_shill_user_profile_dir,
505e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill user profile directory')
506898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_dir('/run/shill/user_profiles',
507e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'Shill profile root')
508898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_link_to('/run/shill/user_profiles/chronos',
509e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                               self.new_shill_user_profile_dir,
510e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                               'Shill profile link')
511069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        self.assure_is_dir(self.user_cryptohome_log_dir,
512069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                           'shill user log directory')
513898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_link_to('/run/shill/log',
514069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                               self.user_cryptohome_log_dir,
515069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                               'Shill logs link')
516e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
517865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                  [ 'InsertUserProfile',
518865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
519865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'CreateProfile and InsertUserProfile '
520865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'are called')
521e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
522e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
5239f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart    def test_login_guest(self):
524e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Tests the guest login process.
525e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
526898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        Login should create a temporary profile directory in /run,
527e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        instead of using one within the root directory for normal users.
528e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
5299f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        """
530898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
5319f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.login_guest()
5329f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure(not os.path.exists(self.flimflam_user_profile),
5339f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                    'Flimflam user profile does not exist')
5349f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure(not os.path.exists(self.old_shill_user_profile),
5359f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                    'Old shill user profile does not exist')
5369f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure(not os.path.exists(self.new_shill_user_profile),
5379f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                    'New shill user profile does not exist')
5389f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure(not os.path.exists(self.new_shill_user_profile_dir),
5399f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                    'New shill user profile directory')
5409f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure_is_dir(self.guest_shill_user_profile_dir,
5419f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                           'shill guest user profile directory')
542898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_dir('/run/shill/user_profiles',
5439f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                           'Shill profile root')
544898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_link_to('/run/shill/user_profiles/chronos',
5459f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                               self.guest_shill_user_profile_dir,
5469f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                               'Shill profile link')
547069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        self.assure_is_dir(self.guest_shill_user_log_dir,
548069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                           'shill guest user log directory')
549898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure_is_link_to('/run/shill/log',
550069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                               self.guest_shill_user_log_dir,
551069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                               'Shill logs link')
5529f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
553865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                  [ 'InsertUserProfile',
554865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', '') ]],
555865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'CreateProfile and InsertUserProfile '
556865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'are called')
5579f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart
558e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
559e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_profile_exists(self):
560e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in a user whose profile already exists.
561e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
562e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should only push (and not create) the user profile
563e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        if a user profile already exists.
564e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
565898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
566e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mkdir(self.new_shill_user_profile_dir)
567e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.touch(self.new_shill_user_profile)
568e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
569865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
570865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
571865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
572e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
573e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
574e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_old_shill_profile(self):
575e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in a user with an old-style shill profile.
576e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
577e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should move an old shill user profile into place
578e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        if a new one does not exist.
579e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
580898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
581e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_old_shill_user_profile(self.magic_header)
582e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
583e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.old_shill_user_profile),
584e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Old shill user profile no longer exists')
5855d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.assure(not os.path.exists(self.old_shill_user_profile_dir),
586e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Old shill user profile directory no longer exists')
587e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_exists(self.new_shill_user_profile,
588e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill profile')
589e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header in
590e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    self.file_contents(self.new_shill_user_profile),
591e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill user profile contains our magic header')
592865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
593865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
594865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
595e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
596e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
597e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def make_symlink(self, path):
598e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a symbolic link named |path|.
599e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
600e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname of the symbolic link.
601e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
602e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
603e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.symlink('/etc/hosts', path)
604e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
605e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
606e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def make_special_file(self, path):
607e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a special file named |path|.
608e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
609e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname of the special file.
610e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
611e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
612e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.mknod(path, stat.S_IFIFO)
613e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
614e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
615e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def make_bad_owner(self, path):
616e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Create a regular file with a strange ownership.
617e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
618e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        @param path string pathname of the file.
619e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
620e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """
621e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.touch(path)
622e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        os.lchown(path, 1000, 1000)
623e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
624e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
625e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_invalid_old_shill_profile(self):
626e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in with an invalid old-style shill profile.
627e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
628e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should ignore non-regular files or files not owned
629e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        by the correct user.  The original file should be removed.
630e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
631e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
632898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
633e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        for file_creation_method in (self.make_symlink,
634e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                                     self.make_special_file,
635e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                                     os.mkdir,
636e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                                     self.make_bad_owner):
6375d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart            os.mkdir(self.old_shill_user_profile_dir)
638e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            file_creation_method(self.old_shill_user_profile)
639e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.login()
640e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.assure(not os.path.exists(self.old_shill_user_profile),
641e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        'Old shill user profile no longer exists')
6425d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart            self.assure(not os.path.exists(self.old_shill_user_profile_dir),
643e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        'Old shill user profile directory no longer exists')
644e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.assure(not os.path.exists(self.new_shill_user_profile),
645e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                        'New shill profile was not created')
646e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart            self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
647865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                      [ 'InsertUserProfile',
648865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                        ('~chronos/shill',
649865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                         self.fake_user_hash) ]],
650865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                     'CreateProfile and InsertUserProfile '
651865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                     'are called')
652898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger            os.unlink('/run/shill/user_profiles/chronos')
653e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
654e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
655e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_ignore_old_shill_profile(self):
656e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in with both an old and new profile present.
657e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
658e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should ignore an old shill user profile if a new one
659e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        exists.
660e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
661e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
662898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
663e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_new_shill_user_profile('')
664e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_old_shill_user_profile(self.magic_header)
665e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
666e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(os.path.exists(self.old_shill_user_profile),
667e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Old shill user profile still exists')
668e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_exists(self.new_shill_user_profile,
669e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill profile')
670e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header not in
671e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    self.file_contents(self.new_shill_user_profile),
672e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill user profile does not contain our magic header')
673865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
674865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
675865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
676e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
677e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
678e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_flimflam_profile(self):
679e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in with an old flimflam profile.
680e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
681e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should move a flimflam user profile into place
682e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        if a shill one does not exist.
683e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
684e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
685898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
686e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_flimflam_user_profile(self.magic_header)
687e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
688e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.flimflam_user_profile),
689e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam user profile no longer exists')
6905d02ca80b41c39e5e9d15fe68323cf6fd45cc119Paul Stewart        self.assure(not os.path.exists(self.flimflam_user_profile_dir),
691e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam user profile directory no longer exists')
692e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_exists(self.new_shill_user_profile,
693e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill profile')
694e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header in
695e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    self.file_contents(self.new_shill_user_profile),
696e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill user profile contains our magic header')
697865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
698865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
699865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
700e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
701e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
702e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_ignore_flimflam_profile(self):
703e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in with both a flimflam profile and a new profile.
704e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
705e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should ignore an old flimflam user profile if a new
706e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        one exists.
707e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
708e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
709898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
710e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_flimflam_user_profile(self.magic_header)
711e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_new_shill_user_profile('')
712e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
713e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_exists(self.new_shill_user_profile,
714e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill profile')
715e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header not in
716e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    self.file_contents(self.new_shill_user_profile),
717e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill user profile does not contain our magic header')
718865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
719865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
720865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
721e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
722e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
723e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_login_prefer_old_shill_profile(self):
724e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test logging in with both a flimflam and old-style shill profile.
725e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
726e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should use the old shill user profile in preference
727e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        to a flimflam user profile if the new user profile does not
728e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        exist.
729e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
730e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        """
731898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
732e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_flimflam_user_profile('')
733e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.create_old_shill_user_profile(self.magic_header)
734e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.login()
735e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.flimflam_user_profile),
736e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Flimflam user profile was removed')
737e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(not os.path.exists(self.old_shill_user_profile),
738e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Old shill user profile no longer exists')
739e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure_exists(self.new_shill_user_profile,
740e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                           'New shill profile')
741e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.assure(self.magic_header in
742e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    self.file_contents(self.new_shill_user_profile),
743e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'Shill user profile contains our magic header')
744865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart        self.assure_method_calls([[ 'InsertUserProfile',
745865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                    ('~chronos/shill', self.fake_user_hash) ]],
746865202aa23c2b6fde1b7d36e0e8096cd5eb51c9aPaul Stewart                                 'Only InsertUserProfile is called')
747e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart
748e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
749d819d541e5908f28e9eb119e389edb1099263a3cPaul Stewart    def test_login_multi_profile(self):
750e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test signalling shill about multiple logged-in users.
751e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
752e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        Login script should not create multiple profiles in parallel
753e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        if called more than once without an intervening logout.  Only
754e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        the initial user profile should be created.
755e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
756d819d541e5908f28e9eb119e389edb1099263a3cPaul Stewart        """
757898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.mkdir('/run/shill')
758d819d541e5908f28e9eb119e389edb1099263a3cPaul Stewart        self.create_new_shill_user_profile('')
759dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart
760dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart        # First logged-in user should create a profile (tested above).
761dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart        self.login()
762dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart
763dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart        # Clear the mock method-call queue.
764dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart        self.mock_flimflam.get_method_calls()
765dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart
766dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart        for attempt in range(5):
767d819d541e5908f28e9eb119e389edb1099263a3cPaul Stewart            self.login()
768dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart            self.assure_method_calls([], 'No more profiles are added to shill')
769898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger            profile_links = os.listdir('/run/shill/user_profiles')
770dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart            self.assure(len(profile_links) == 1, 'Only one profile exists')
771dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart            self.assure(profile_links[0] == 'chronos',
772dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart                        'The profile link is for the chronos user')
773898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger            self.assure_is_link_to('/run/shill/log',
774069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                                   self.user_cryptohome_log_dir,
775dc6a58d64864c4f12da00123227efa778b740e1dPaul Stewart                                   'Shill log link for chronos')
776d819d541e5908f28e9eb119e389edb1099263a3cPaul Stewart
777e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart
778e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart    def test_logout(self):
779e124f7c5088906baf46972ad81d1c5faf4c97dcfPaul Stewart        """ Test the logout process. """
780898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        os.makedirs('/run/shill/user_profiles')
7819f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        os.makedirs(self.guest_shill_user_profile_dir)
782069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        os.makedirs(self.guest_shill_user_log_dir)
783898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.touch('/run/state/logged-in')
784e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart        self.logout()
785898bd550e04f770a321eb7daf8ab70732d06c3d7Mike Frysinger        self.assure(not os.path.exists('/run/shill/user_profiles'),
786e10e707a71de78209daaba21e0d3bb7d951ba4afPaul Stewart                    'User profile directory was removed')
7879f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart        self.assure(not os.path.exists(self.guest_shill_user_profile_dir),
7889f29def08d6ff2f472aee180bee3bc22f8880c74Paul Stewart                    'Guest user profile directory was removed')
789069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley        self.assure(not os.path.exists(self.guest_shill_user_log_dir),
790069e25d06772526a545078266dc1b1e578a44c0cChristopher Wiley                    'Guest user log directory was removed')
791c1127ce2c01efb763bb7f64cbe255871239c7235Paul Stewart        self.assure_method_calls([[ 'PopAllUserProfiles', '' ]],
792c1127ce2c01efb763bb7f64cbe255871239c7235Paul Stewart                                 'PopAllUserProfiles is called')
793