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',
                         ]
    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.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('--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')
