import grp
import mock_flimflam
import os
import pwd
import stat
import time
import utils

from autotest_lib.client.bin import test
from autotest_lib.client.common_lib import error

class network_ShillInitScripts(test.test):
    """ Test that shill init scripts perform as expected.  Use the
        real filesystem (doing a best effort to archive and restore
        current state).  The shill manager is stopped and a proxy
        DBus entity is installed to accept DBus messages that are sent
        via "dbus-send" in the shill startup scripts.  However, the
        "real" shill is still also started from time to time and we
        check that it is run with the right command line arguments.
    """
    version = 1
    save_directories = [ '/var/cache/shill',
                         '/var/cache/flimflam',
                         '/run/shill',
                         '/run/state/logged-in',
                         '/run/dhcpcd',
                         '/var/lib/dhcpcd',
                         '/home/chronos/.disable_shill' ]
    fake_user = 'not-a-real-user@chromium.org'
    saved_config = '/tmp/network_ShillInitScripts_saved_config.tgz'
    cryptohome_path_command = 'cryptohome-path'
    guest_shill_user_profile_dir = '/run/shill/guest_user_profile/shill'
    guest_shill_user_log_dir = '/run/shill/guest_user_profile/shill_logs'
    magic_header = '# --- shill init file test magic header ---'


    def start_shill(self):
        """ Starts a shill instance. """
        utils.start_service('shill')


    def stop_shill(self):
        """ Halt the running shill instance. """
        utils.stop_service('shill', ignore_status=True)

        for attempt in range(10):
            if not self.find_pid('shill'):
                break
            time.sleep(1)
        else:
            raise error.TestFail('Shill process does not appear to be dying')


    def login(self, user=None):
        """ Simulate the login process.

        Note: "start" blocks until the "script" block completes.

        @param user string user name (email address) to log in.

        """

        if utils.has_systemd():
            start_cmd = (('systemctl set-environment CHROMEOS_USER=%s'
                          ' && systemctl start shill-start-user-session') %
                         (user or self.fake_user))
        else:
            start_cmd = ('start shill-start-user-session CHROMEOS_USER=%s' %
                         (user or self.fake_user))
        utils.system(start_cmd)


    def login_guest(self):
        """ Simulate guest login.

        For guest login, session-manager passes an empty CHROMEOS_USER arg.

        """
        self.login('""')


    def logout(self):
        """ Simulate user logout.

        Note: "start" blocks until the "script" block completes.

        """
        utils.start_service('shill-stop-user-session')


    def start_test(self):
        """ Setup the start of the test.  Stop shill and create test harness."""
        # Stop a system process on test duts for keeping connectivity up.
        ret = utils.stop_service('recover_duts', ignore_status=True)
        self.recover_duts_stopped = (ret == 0);

        self.stop_shill()

        # Deduce the root cryptohome directory name for our fake user.
        self.root_cryptohome_dir = utils.system_output(
            '%s system %s' % (self.cryptohome_path_command, self.fake_user))

        # Deduce the user cryptohome directory name for our fake user.
        self.user_cryptohome_dir = utils.system_output(
            '%s user %s' % (self.cryptohome_path_command, self.fake_user))

        # Deduce the directory for memory log storage.
        self.user_cryptohome_log_dir = ('%s/shill_logs' %
                                        self.root_cryptohome_dir)

        # The sanitized hash of the username is the basename of the cryptohome.
        self.fake_user_hash = os.path.basename(self.root_cryptohome_dir)

        # Just in case this hash actually exists, add these to the list of
        # saved directories.
        self.save_directories.append(self.root_cryptohome_dir)
        self.save_directories.append(self.user_cryptohome_dir)

        # Archive the system state we will be modifying, then remove them.
        utils.system('tar zcvf %s --directory / --ignore-failed-read %s'
                     ' 2>/dev/null' %
                     (self.saved_config, ' '.join(self.save_directories)))
        utils.system('rm -rf %s' % ' '.join(self.save_directories),
                     ignore_status=True)

        # Create the fake user's system cryptohome directory.
        os.mkdir(self.root_cryptohome_dir)
        self.new_shill_user_profile_dir = ('%s/shill' %
                                           self.root_cryptohome_dir)
        self.new_shill_user_profile = ('%s/shill.profile' %
                                       self.new_shill_user_profile_dir)

        # Create the fake user's user cryptohome directory.
        os.mkdir(self.user_cryptohome_dir)
        self.flimflam_user_profile_dir = ('%s/flimflam' %
                                          self.user_cryptohome_dir)
        self.flimflam_user_profile = ('%s/flimflam.profile' %
                                      self.flimflam_user_profile_dir)
        self.old_shill_user_profile_dir = ('%s/shill' %
                                           self.user_cryptohome_dir)
        self.old_shill_user_profile = ('%s/shill.profile' %
                                       self.old_shill_user_profile_dir)
        self.mock_flimflam = None


    def start_mock_flimflam(self):
        """ Start a mock flimflam instance to accept and log DBus calls. """
        self.mock_flimflam = mock_flimflam.MockFlimflam()
        self.mock_flimflam.start()


    def erase_state(self):
        """ Remove all the test harness files. """
        utils.system('rm -rf %s' % ' '.join(self.save_directories))
        os.mkdir(self.root_cryptohome_dir)
        os.mkdir(self.user_cryptohome_dir)


    def end_test(self):
        """ Perform cleanup at the end of the test. """
        if self.mock_flimflam:
            self.mock_flimflam.quit()
            self.mock_flimflam.join()
        self.erase_state()
        utils.system('tar zxvf %s --directory /' % self.saved_config)
        utils.system('rm -f %s' % self.saved_config)
        self.restart_system_processes()


    def restart_system_processes(self):
        """ Restart vital system services at the end of the test. """
        utils.start_service('shill', ignore_status=True)
        if self.recover_duts_stopped:
            utils.start_service('recover_duts', ignore_status=True)


    def assure(self, must_be_true, assertion_name):
        """ Perform a named assertion.

        @param must_be_true boolean parameter that must be true.
        @param assertion_name string name of this assertion.

        """
        if not must_be_true:
            raise error.TestFail('%s: Assertion failed: %s' %
                                 (self.test_name, assertion_name))


    def assure_path_owner(self, path, owner):
        """ Assert that |path| is owned by |owner|.

        @param path string pathname to test.
        @param owner string user name that should own |path|.

        """
        self.assure(pwd.getpwuid(os.stat(path).st_uid)[0] == owner,
                    'Path %s is owned by %s' % (path, owner))


    def assure_path_group(self, path, group):
        """ Assert that |path| is owned by |group|.

        @param path string pathname to test.
        @param group string group name that should own |path|.

        """
        self.assure(grp.getgrgid(os.stat(path).st_gid)[0] == group,
                    'Path %s is group-owned by %s' % (path, group))


    def assure_exists(self, path, path_friendly_name):
        """ Assert that |path| exists.

        @param path string pathname to test.
        @param path_friendly_name string user-parsable description of |path|.

        """
        self.assure(os.path.exists(path), '%s exists' % path_friendly_name)


    def assure_is_dir(self, path, path_friendly_name):
        """ Assert that |path| is a directory.

        @param path string pathname to test.
        @param path_friendly_name string user-parsable description of |path|.

        """
        self.assure_exists(path, path_friendly_name)
        self.assure(stat.S_ISDIR(os.lstat(path).st_mode),
                    '%s is a directory' % path_friendly_name)


    def assure_is_link(self, path, path_friendly_name):
        """ Assert that |path| is a symbolic link.

        @param path string pathname to test.
        @param path_friendly_name string user-parsable description of |path|.

        """
        self.assure_exists(path, path_friendly_name)
        self.assure(stat.S_ISLNK(os.lstat(path).st_mode),
                    '%s is a symbolic link' % path_friendly_name)


    def assure_is_link_to(self, path, pointee, path_friendly_name):
        """ Assert that |path| is a symbolic link to |pointee|.

        @param path string pathname to test.
        @param pointee string pathname that |path| should point to.
        @param path_friendly_name string user-parsable description of |path|.

        """
        self.assure_is_link(path, path_friendly_name)
        self.assure(os.readlink(path) == pointee,
                    '%s is a symbolic link to %s' %
                    (path_friendly_name, pointee))


    def assure_method_calls(self, expected_method_calls, assertion_name):
        """ Assert that |expected_method_calls| were executed on mock_flimflam.

        @param expected_method_calls list of string-tuple pairs of method
            name + tuple of arguments.
        @param assertion_name string name to assign to the assertion.

        """
        method_calls = self.mock_flimflam.get_method_calls()
        if len(expected_method_calls) != len(method_calls):
            self.assure(False, '%s: method call count does not match' %
                        assertion_name)
        for expected, actual in zip(expected_method_calls, method_calls):
            self.assure(actual.method == expected[0],
                        '%s: method %s matches expected %s' %
                        (assertion_name, actual.method, expected[0]))
            self.assure(actual.argument == expected[1],
                        '%s: argument %s matches expected %s' %
                        (assertion_name, actual.argument, expected[1]))


    def create_file_with_contents(self, filename, contents):
        """ Create a file named |filename| that contains |contents|.

        @param filename string name of file.
        @param contents string contents of file.

        """
        with open(filename, 'w') as f:
            f.write(contents)


    def touch(self, filename):
        """ Create an empty file named |filename|.

        @param filename string name of file.

        """
        self.create_file_with_contents(filename, '')


    def create_new_shill_user_profile(self, contents):
        """ Create a fake new user profile with |contents|.

        @param contents string contents of the new user profile.

        """
        os.mkdir(self.new_shill_user_profile_dir)
        self.create_file_with_contents(self.new_shill_user_profile, contents)


    def create_old_shill_user_profile(self, contents):
        """ Create a fake old-style user profile with |contents|.

        @param contents string contents of the old user profile.

        """
        os.mkdir(self.old_shill_user_profile_dir)
        self.create_file_with_contents(self.old_shill_user_profile, contents)


    def create_flimflam_user_profile(self, contents):
        """ Create a legacy flimflam user profile with |contents|.

        @param contents string contents of the flimflam user profile.

        """
        os.mkdir(self.flimflam_user_profile_dir)
        self.create_file_with_contents(self.flimflam_user_profile, contents)


    def file_contents(self, filename):
        """ Returns the contents of |filename|.

        @param filename string name of file to read.

        """
        with open(filename) as f:
            return f.read()


    def find_pid(self, process_name):
        """ Returns the process id of |process_name|.

        @param process_name string name of process to search for.

        """
        return utils.system_output('pgrep %s' % process_name,
                                   ignore_status=True).split('\n')[0]


    def get_commandline(self):
        """ Returns the command line of the current shill executable. """
        pid = self.find_pid('shill')
        return file('/proc/%s/cmdline' % pid).read().split('\0')


    def run_once(self):
        """ Main test loop. """
        try:
            self.start_test()
        except:
            self.restart_system_processes()
            raise

        try:
            self.run_tests([
                self.test_start_shill,
                self.test_start_logged_in,
                self.test_start_port_flimflam_profile])

            # The tests above run a real instance of shill, whereas the tests
            # below rely on a mock instance of shill.  We must take care not
            # to run the mock at the same time as a real shill instance.
            self.start_mock_flimflam()

            self.run_tests([
                self.test_login,
                self.test_login_guest,
                self.test_login_profile_exists,
                self.test_login_old_shill_profile,
                self.test_login_invalid_old_shill_profile,
                self.test_login_ignore_old_shill_profile,
                self.test_login_flimflam_profile,
                self.test_login_ignore_flimflam_profile,
                self.test_login_prefer_old_shill_profile,
                self.test_login_multi_profile,
                self.test_logout])
        finally:
            # Stop any shill instances started during testing.
            self.stop_shill()
            self.end_test()


    def run_tests(self, tests):
        """ Executes each of the test subparts in sequence.

        @param tests list of methods to run.

        """
        for test in tests:
          self.test_name = test.__name__
          test()
          self.stop_shill()
          self.erase_state()


    def test_start_shill(self):
        """ Test all created pathnames during shill startup.

        Also ensure the push argument is not provided by default.

        """
        self.touch('/home/chronos/.disable_shill')
        self.start_shill()
        self.assure_is_dir('/run/shill', 'Shill run directory')
        self.assure_is_dir('/var/lib/dhcpcd', 'dhcpcd lib directory')
        self.assure_path_owner('/var/lib/dhcpcd', 'dhcp')
        self.assure_path_group('/var/lib/dhcpcd', 'dhcp')
        self.assure_is_dir('/run/dhcpcd', 'dhcpcd run directory')
        self.assure_path_owner('/run/dhcpcd', 'dhcp')
        self.assure_path_group('/run/dhcpcd', 'dhcp')
        self.assure(not os.path.exists('/home/chronos/.disable_shill'),
                    'Shill disable file does not exist')
        self.assure('--push=~chronos/shill' not in self.get_commandline(),
                    'Shill command line does not contain push argument')


    def test_start_logged_in(self):
        """ Tests starting up shill while a user is already logged in.

        The "--push" argument should not be added even though shill is started
        while a user is logged in.

        """
        os.mkdir('/run/shill')
        os.mkdir('/run/shill/user_profiles')
        self.create_new_shill_user_profile('')
        os.symlink(self.new_shill_user_profile_dir,
                   '/run/shill/user_profiles/chronos')
        self.touch('/run/state/logged-in')
        self.start_shill()
        self.assure('--push=~chronos/shill' not in self.get_commandline(),
                    'Shill command line does not contain push argument')
        os.unlink('/run/state/logged-in')


    def test_start_port_flimflam_profile(self):
        """ Test that we can port a flimflam profile to a new shill profile.

        Startup should move an old flimflam profile into place if a shill
        profile does not already exist.

        """
        os.mkdir('/var/cache/flimflam')
        flimflam_profile = '/var/cache/flimflam/default.profile'
        self.create_file_with_contents(flimflam_profile, self.magic_header)
        shill_profile = '/var/cache/shill/default.profile'
        self.start_shill()
        self.assure(not os.path.exists(flimflam_profile),
                    'Flimflam profile no longer exists')
        self.assure(os.path.exists(shill_profile),
                    'Shill profile exists')
        self.assure(self.magic_header in self.file_contents(shill_profile),
                    'Shill default profile contains our magic header')


    def test_start_ignore_flimflam_profile(self):
        """ Test that we ignore a flimflam profile if a new profile exists.

        Startup should ignore an old flimflam profile if a shill profile
        already exists.

        """
        os.mkdir('/var/cache/flimflam')
        os.mkdir('/var/cache/shill')
        flimflam_profile = '/var/cache/flimflam/default.profile'
        self.create_file_with_contents(flimflam_profile, self.magic_header)
        shill_profile = '/var/cache/shill/default.profile'
        self.touch(shill_profile)
        self.start_shill()
        self.assure(os.path.exists(flimflam_profile),
                    'Flimflam profile still exists')
        self.assure(self.magic_header not in self.file_contents(shill_profile),
                    'Shill default profile does not contain our magic header')


    def test_login(self):
        """ Test the login process.

        Login should create a profile directory, then create and push
        a user profile, given no previous state.

        """
        os.mkdir('/run/shill')
        self.login()
        self.assure(not os.path.exists(self.flimflam_user_profile),
                    'Flimflam user profile does not exist')
        self.assure(not os.path.exists(self.old_shill_user_profile),
                    'Old shill user profile does not exist')
        self.assure(not os.path.exists(self.new_shill_user_profile),
                    'New shill user profile does not exist')
        # The DBus "CreateProfile" method should have been handled
        # by our mock_flimflam instance, so the profile directory
        # should not have actually been created.
        self.assure_is_dir(self.new_shill_user_profile_dir,
                           'New shill user profile directory')
        self.assure_is_dir('/run/shill/user_profiles',
                           'Shill profile root')
        self.assure_is_link_to('/run/shill/user_profiles/chronos',
                               self.new_shill_user_profile_dir,
                               'Shill profile link')
        self.assure_is_dir(self.user_cryptohome_log_dir,
                           'shill user log directory')
        self.assure_is_link_to('/run/shill/log',
                               self.user_cryptohome_log_dir,
                               'Shill logs link')
        self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
                                  [ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'CreateProfile and InsertUserProfile '
                                 'are called')


    def test_login_guest(self):
        """ Tests the guest login process.

        Login should create a temporary profile directory in /run,
        instead of using one within the root directory for normal users.

        """
        os.mkdir('/run/shill')
        self.login_guest()
        self.assure(not os.path.exists(self.flimflam_user_profile),
                    'Flimflam user profile does not exist')
        self.assure(not os.path.exists(self.old_shill_user_profile),
                    'Old shill user profile does not exist')
        self.assure(not os.path.exists(self.new_shill_user_profile),
                    'New shill user profile does not exist')
        self.assure(not os.path.exists(self.new_shill_user_profile_dir),
                    'New shill user profile directory')
        self.assure_is_dir(self.guest_shill_user_profile_dir,
                           'shill guest user profile directory')
        self.assure_is_dir('/run/shill/user_profiles',
                           'Shill profile root')
        self.assure_is_link_to('/run/shill/user_profiles/chronos',
                               self.guest_shill_user_profile_dir,
                               'Shill profile link')
        self.assure_is_dir(self.guest_shill_user_log_dir,
                           'shill guest user log directory')
        self.assure_is_link_to('/run/shill/log',
                               self.guest_shill_user_log_dir,
                               'Shill logs link')
        self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
                                  [ 'InsertUserProfile',
                                    ('~chronos/shill', '') ]],
                                 'CreateProfile and InsertUserProfile '
                                 'are called')


    def test_login_profile_exists(self):
        """ Test logging in a user whose profile already exists.

        Login script should only push (and not create) the user profile
        if a user profile already exists.
        """
        os.mkdir('/run/shill')
        os.mkdir(self.new_shill_user_profile_dir)
        self.touch(self.new_shill_user_profile)
        self.login()
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def test_login_old_shill_profile(self):
        """ Test logging in a user with an old-style shill profile.

        Login script should move an old shill user profile into place
        if a new one does not exist.
        """
        os.mkdir('/run/shill')
        self.create_old_shill_user_profile(self.magic_header)
        self.login()
        self.assure(not os.path.exists(self.old_shill_user_profile),
                    'Old shill user profile no longer exists')
        self.assure(not os.path.exists(self.old_shill_user_profile_dir),
                    'Old shill user profile directory no longer exists')
        self.assure_exists(self.new_shill_user_profile,
                           'New shill profile')
        self.assure(self.magic_header in
                    self.file_contents(self.new_shill_user_profile),
                    'Shill user profile contains our magic header')
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def make_symlink(self, path):
        """ Create a symbolic link named |path|.

        @param path string pathname of the symbolic link.

        """
        os.symlink('/etc/hosts', path)


    def make_special_file(self, path):
        """ Create a special file named |path|.

        @param path string pathname of the special file.

        """
        os.mknod(path, stat.S_IFIFO)


    def make_bad_owner(self, path):
        """ Create a regular file with a strange ownership.

        @param path string pathname of the file.

        """
        self.touch(path)
        os.lchown(path, 1000, 1000)


    def test_login_invalid_old_shill_profile(self):
        """ Test logging in with an invalid old-style shill profile.

        Login script should ignore non-regular files or files not owned
        by the correct user.  The original file should be removed.

        """
        os.mkdir('/run/shill')
        for file_creation_method in (self.make_symlink,
                                     self.make_special_file,
                                     os.mkdir,
                                     self.make_bad_owner):
            os.mkdir(self.old_shill_user_profile_dir)
            file_creation_method(self.old_shill_user_profile)
            self.login()
            self.assure(not os.path.exists(self.old_shill_user_profile),
                        'Old shill user profile no longer exists')
            self.assure(not os.path.exists(self.old_shill_user_profile_dir),
                        'Old shill user profile directory no longer exists')
            self.assure(not os.path.exists(self.new_shill_user_profile),
                        'New shill profile was not created')
            self.assure_method_calls([[ 'CreateProfile', '~chronos/shill' ],
                                      [ 'InsertUserProfile',
                                        ('~chronos/shill',
                                         self.fake_user_hash) ]],
                                     'CreateProfile and InsertUserProfile '
                                     'are called')
            os.unlink('/run/shill/user_profiles/chronos')


    def test_login_ignore_old_shill_profile(self):
        """ Test logging in with both an old and new profile present.

        Login script should ignore an old shill user profile if a new one
        exists.

        """
        os.mkdir('/run/shill')
        self.create_new_shill_user_profile('')
        self.create_old_shill_user_profile(self.magic_header)
        self.login()
        self.assure(os.path.exists(self.old_shill_user_profile),
                    'Old shill user profile still exists')
        self.assure_exists(self.new_shill_user_profile,
                           'New shill profile')
        self.assure(self.magic_header not in
                    self.file_contents(self.new_shill_user_profile),
                    'Shill user profile does not contain our magic header')
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def test_login_flimflam_profile(self):
        """ Test logging in with an old flimflam profile.

        Login script should move a flimflam user profile into place
        if a shill one does not exist.

        """
        os.mkdir('/run/shill')
        self.create_flimflam_user_profile(self.magic_header)
        self.login()
        self.assure(not os.path.exists(self.flimflam_user_profile),
                    'Flimflam user profile no longer exists')
        self.assure(not os.path.exists(self.flimflam_user_profile_dir),
                    'Flimflam user profile directory no longer exists')
        self.assure_exists(self.new_shill_user_profile,
                           'New shill profile')
        self.assure(self.magic_header in
                    self.file_contents(self.new_shill_user_profile),
                    'Shill user profile contains our magic header')
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def test_login_ignore_flimflam_profile(self):
        """ Test logging in with both a flimflam profile and a new profile.

        Login script should ignore an old flimflam user profile if a new
        one exists.

        """
        os.mkdir('/run/shill')
        self.create_flimflam_user_profile(self.magic_header)
        self.create_new_shill_user_profile('')
        self.login()
        self.assure_exists(self.new_shill_user_profile,
                           'New shill profile')
        self.assure(self.magic_header not in
                    self.file_contents(self.new_shill_user_profile),
                    'Shill user profile does not contain our magic header')
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def test_login_prefer_old_shill_profile(self):
        """ Test logging in with both a flimflam and old-style shill profile.

        Login script should use the old shill user profile in preference
        to a flimflam user profile if the new user profile does not
        exist.

        """
        os.mkdir('/run/shill')
        self.create_flimflam_user_profile('')
        self.create_old_shill_user_profile(self.magic_header)
        self.login()
        self.assure(not os.path.exists(self.flimflam_user_profile),
                    'Flimflam user profile was removed')
        self.assure(not os.path.exists(self.old_shill_user_profile),
                    'Old shill user profile no longer exists')
        self.assure_exists(self.new_shill_user_profile,
                           'New shill profile')
        self.assure(self.magic_header in
                    self.file_contents(self.new_shill_user_profile),
                    'Shill user profile contains our magic header')
        self.assure_method_calls([[ 'InsertUserProfile',
                                    ('~chronos/shill', self.fake_user_hash) ]],
                                 'Only InsertUserProfile is called')


    def test_login_multi_profile(self):
        """ Test signalling shill about multiple logged-in users.

        Login script should not create multiple profiles in parallel
        if called more than once without an intervening logout.  Only
        the initial user profile should be created.

        """
        os.mkdir('/run/shill')
        self.create_new_shill_user_profile('')

        # First logged-in user should create a profile (tested above).
        self.login()

        # Clear the mock method-call queue.
        self.mock_flimflam.get_method_calls()

        for attempt in range(5):
            self.login()
            self.assure_method_calls([], 'No more profiles are added to shill')
            profile_links = os.listdir('/run/shill/user_profiles')
            self.assure(len(profile_links) == 1, 'Only one profile exists')
            self.assure(profile_links[0] == 'chronos',
                        'The profile link is for the chronos user')
            self.assure_is_link_to('/run/shill/log',
                                   self.user_cryptohome_log_dir,
                                   'Shill log link for chronos')


    def test_logout(self):
        """ Test the logout process. """
        os.makedirs('/run/shill/user_profiles')
        os.makedirs(self.guest_shill_user_profile_dir)
        os.makedirs(self.guest_shill_user_log_dir)
        self.touch('/run/state/logged-in')
        self.logout()
        self.assure(not os.path.exists('/run/shill/user_profiles'),
                    'User profile directory was removed')
        self.assure(not os.path.exists(self.guest_shill_user_profile_dir),
                    'Guest user profile directory was removed')
        self.assure(not os.path.exists(self.guest_shill_user_log_dir),
                    'Guest user log directory was removed')
        self.assure_method_calls([[ 'PopAllUserProfiles', '' ]],
                                 'PopAllUserProfiles is called')
