From c3bf0c99e6b8915eefda3581d7adc7627c6418c6 Mon Sep 17 00:00:00 2001 From: Adam Gashlin Date: Mon, 6 Aug 2018 14:40:00 -0700 Subject: [PATCH] Bug 1480612: Test Register Application Restart more thoroughly. r=whimboo --- .../sessionstore/session_store_test_case.py | 55 ++++++++- ..._restore_windows_after_windows_shutdown.py | 114 +++++++++++------- 2 files changed, 120 insertions(+), 49 deletions(-) diff --git a/testing/firefox-ui/tests/functional/sessionstore/session_store_test_case.py b/testing/firefox-ui/tests/functional/sessionstore/session_store_test_case.py index 8d7e738cc88a..d523a5dd5bf9 100644 --- a/testing/firefox-ui/tests/functional/sessionstore/session_store_test_case.py +++ b/testing/firefox-ui/tests/functional/sessionstore/session_store_test_case.py @@ -8,7 +8,8 @@ class SessionStoreTestCase(PuppeteerMixin, MarionetteTestCase): - def setUp(self, startup_page=1, include_private=True, no_auto_updates=True): + def setUp(self, startup_page=1, include_private=True, no_auto_updates=True, + win_register_restart=False): super(SessionStoreTestCase, self).setUp() # Each list element represents a window of tabs loaded at # some testing URL @@ -45,6 +46,8 @@ def setUp(self, startup_page=1, include_private=True, no_auto_updates=True): # send us session updates unless the parent has explicitly asked # for them via the TabStateFlusher. 'browser.sessionstore.debug.no_auto_updates': no_auto_updates, + # Whether to enable the register application restart mechanism. + 'toolkit.winRegisterApplicationRestart': win_register_restart, }) self.all_windows = self.test_windows.copy() @@ -92,7 +95,6 @@ def open_windows(self, window_sets, is_private=False): Whether or not any new windows should be a private browsing windows. """ - if (is_private): win = self.browser.open_browser(is_private=True) win.switch_to() @@ -152,7 +154,6 @@ def simulate_os_shutdown(self): :raises: Exception: if not supported on the current platform :raises: WindowsError: if a Windows API call failed """ - if self.marionette.session_capabilities['platformName'] != 'windows': raise Exception('Unsupported platform for simulate_os_shutdown') @@ -175,7 +176,6 @@ def _shutdown_with_windows_restart_manager(self, pid): :raises: WindowsError: if a Windows API call fails """ - import ctypes from ctypes import Structure, POINTER, WINFUNCTYPE, windll, pointer, WinError from ctypes.wintypes import HANDLE, DWORD, BOOL, WCHAR, UINT, ULONG, LPCWSTR @@ -283,3 +283,50 @@ class GUID(ctypes.Structure): finally: RmEndSession(dwSessionHandle) + + def windows_shutdown_with_variety(self, restart_by_os, expect_restore): + """ Test restoring windows after Windows shutdown. + + Opens a set of windows, both standard and private, with + some number of tabs in them. Once the tabs have loaded, shuts down + the browser with the Windows Restart Manager and restarts the browser. + + This specifically exercises the Windows synchronous shutdown mechanism, + which terminates the process in response to the Restart Manager's + WM_ENDSESSION message. + + If restart_by_os is True, the -os-restarted arg is passed when restarting, + simulating being automatically restarted by the Restart Manager. + + If expect_restore is True, this ensures that the standard tabs have been + restored, and that the private ones have not. Otherwise it ensures that + no tabs and windows have been restored. + """ + current_windows_set = self.convert_open_windows_to_set() + self.assertEqual(current_windows_set, self.all_windows, + msg='Not all requested windows have been opened. Expected {}, got {}.' + .format(self.all_windows, current_windows_set)) + + self.marionette.quit(in_app=True, callback=lambda: self.simulate_os_shutdown()) + + saved_args = self.marionette.instance.app_args + try: + if restart_by_os: + self.marionette.instance.app_args = ['-os-restarted'] + + self.marionette.start_session() + self.marionette.set_context('chrome') + finally: + self.marionette.instance.app_args = saved_args + + current_windows_set = self.convert_open_windows_to_set() + if expect_restore: + self.assertEqual(current_windows_set, self.test_windows, + msg="""Non private browsing windows should have + been restored. Expected {}, got {}. + """.format(self.test_windows, current_windows_set)) + else: + self.assertEqual(len(self.puppeteer.windows.all), 1, + msg='Windows from last session shouldn`t have been restored.') + self.assertEqual(len(self.puppeteer.windows.current.tabbar.tabs), 1, + msg='Tabs from last session shouldn`t have been restored.') diff --git a/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_windows_shutdown.py b/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_windows_shutdown.py index f7883d0ab271..fd031226f257 100644 --- a/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_windows_shutdown.py +++ b/testing/firefox-ui/tests/functional/sessionstore/test_restore_windows_after_windows_shutdown.py @@ -1,45 +1,69 @@ -# This Source Code Form is subject to the terms of the Mozilla Public -# License, v. 2.0. If a copy of the MPL was not distributed with this -# file, You can obtain one at http://mozilla.org/MPL/2.0/. - -# add this directory to the path -import sys -import os -sys.path.append(os.path.dirname(__file__)) - -from session_store_test_case import SessionStoreTestCase - - -class TestSessionStoreWindowsShutdown(SessionStoreTestCase): - - def setUp(self): - super(TestSessionStoreWindowsShutdown, self).setUp(startup_page=3, no_auto_updates=False) - - def test_with_variety(self): - """ Test restoring a set of windows across Windows shutdown. - - Opens a set of windows, both standard and private, with - some number of tabs in them. Once the tabs have loaded, shuts down - the browser with the Windows Restart Manager, restarts the browser, - and then ensures that the standard tabs have been restored, - and that the private ones have not. - - This specifically exercises the Windows synchronous shutdown - mechanism, which terminates the process in response to the - Restart Manager's WM_ENDSESSION message. - """ - - current_windows_set = self.convert_open_windows_to_set() - self.assertEqual(current_windows_set, self.all_windows, - msg='Not all requested windows have been opened. Expected {}, got {}.' - .format(self.all_windows, current_windows_set)) - - self.marionette.quit(in_app=True, callback=lambda: self.simulate_os_shutdown()) - self.marionette.start_session() - self.marionette.set_context('chrome') - - current_windows_set = self.convert_open_windows_to_set() - self.assertEqual(current_windows_set, self.test_windows, - msg="""Non private browsing windows should have - been restored. Expected {}, got {}. - """.format(self.test_windows, current_windows_set)) +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# add this directory to the path +import sys +import os +sys.path.append(os.path.dirname(__file__)) + +from session_store_test_case import SessionStoreTestCase + +# We test the following combinations with simulated Windows shutdown: +# - Start page = restore session (expect restore in all cases) +# - RAR (toolkit.winRegisterApplicationRestart) disabled +# - RAR enabled, restarted manually +# +# - Start page = home +# - RAR disabled (no restore) +# - RAR enabled: +# - restarted by OS (restore) +# - restarted manually (no restore) + + +class TestWindowsShutdown(SessionStoreTestCase): + def setUp(self): + super(TestWindowsShutdown, self).setUp( + startup_page=3, + no_auto_updates=False) + + def test_with_variety(self): + """Test session restore selected by user.""" + self.windows_shutdown_with_variety(restart_by_os=False, expect_restore=True) + + +class TestWindowsShutdownRegisterRestart(SessionStoreTestCase): + def setUp(self): + super(TestWindowsShutdownRegisterRestart, self).setUp( + startup_page=3, + no_auto_updates=False, + win_register_restart=True) + + def test_manual_restart(self): + """Test that restore tabs works in case of register restart failure.""" + self.windows_shutdown_with_variety(restart_by_os=False, expect_restore=True) + + +class TestWindowsShutdownNormal(SessionStoreTestCase): + def setUp(self): + super(TestWindowsShutdownNormal, self).setUp( + no_auto_updates=False) + + def test_with_variety(self): + """Test that windows are not restored on a normal restart.""" + self.windows_shutdown_with_variety(restart_by_os=False, expect_restore=False) + + +class TestWindowsShutdownForcedSessionRestore(SessionStoreTestCase): + def setUp(self): + super(TestWindowsShutdownForcedSessionRestore, self).setUp( + no_auto_updates=False, + win_register_restart=True) + + def test_os_restart(self): + """Test that register application restart restores the session.""" + self.windows_shutdown_with_variety(restart_by_os=True, expect_restore=True) + + def test_manual_restart(self): + """Test that OS shutdown is ignored on manual start.""" + self.windows_shutdown_with_variety(restart_by_os=False, expect_restore=False)