1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import errno, os, stat
6
7from autotest_lib.client.bin import test, utils
8from autotest_lib.client.common_lib import error
9from autotest_lib.client.common_lib.cros import chrome
10from autotest_lib.client.cros import constants, httpd
11
12
13def _respond_with_cookies(handler, url_args):
14    """set_cookie response.
15
16    Responds with a Set-Cookie header to any GET request, and redirects to a
17    chosen URL.
18
19    @param handler: handler for set_cookie.
20    @param url_args: arguments passed through the url.
21
22    """
23    handler.send_response(303)
24    handler.send_header('Set-Cookie', 'name=value')
25    handler.send_header('Location', url_args['continue'][0])
26    handler.end_headers()
27    handler.wfile.write('Got form data:\n')
28    handler.wfile.write('%s:\n' % url_args)
29
30
31class login_ChromeProfileSanitary(test.test):
32    """Tests that the browser uses the correct profile after a crash."""
33    version = 1
34
35
36    def __get_cookies_mtime(self):
37        try:
38            cookies_info = os.stat(constants.LOGIN_PROFILE + '/Cookies')
39            return cookies_info[stat.ST_MTIME]
40        except OSError as e:
41            if e.errno == errno.ENOENT:
42                return None
43            raise
44
45
46    def initialize(self):
47        spec = 'http://localhost:8000'
48        path = '/set_cookie'
49        self._wait_path = '/test_over'
50        self._test_url = spec + path + '?continue=' + spec + self._wait_path
51        self._testServer = httpd.HTTPListener(8000, docroot=self.srcdir)
52        self._testServer.add_url_handler(path, _respond_with_cookies)
53        self._testServer.run()
54
55
56    def cleanup(self):
57        self._testServer.stop()
58
59
60    def run_once(self, timeout=10):
61        with chrome.Chrome() as cr:
62            # Get Default/Cookies mtime. None means no Cookies DB.
63            cookies_mtime = self.__get_cookies_mtime()
64
65            # Wait for chrome to show, then "crash" it.
66            utils.nuke_process_by_name(constants.BROWSER, with_prejudice=True)
67
68            cr.wait_for_browser_to_come_up()
69
70            latch = self._testServer.add_wait_url(self._wait_path)
71
72            # Navigate to site that leaves cookies.
73            cr.browser.tabs[0].Navigate(self._test_url)
74            latch.wait(timeout)
75            if not latch.is_set():
76                raise error.TestError('Never received callback from browser.')
77
78        # Ensure chrome writes state to disk.
79        with chrome.Chrome():
80            # Check mtime of Default/Cookies.  If changed, KABLOOEY.
81            new_cookies_mtime = self.__get_cookies_mtime()
82
83            if cookies_mtime != new_cookies_mtime:
84                if not cookies_mtime and new_cookies_mtime:
85                    raise error.TestFail('Cookies created in Default profile!')
86                raise error.TestFail('Cookies in Default profile changed!')
87