Back to index

unity  6.0.0
__init__.py
Go to the documentation of this file.
00001 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
00002 # Copyright 2012 Canonical
00003 # Author: Thomi Richards
00004 #
00005 # This program is free software: you can redistribute it and/or modify it
00006 # under the terms of the GNU General Public License version 3, as published
00007 # by the Free Software Foundation.
00008 
00009 """Autopilot test case class for Unity-specific tests."""
00010 
00011 from __future__ import absolute_import
00012 
00013 from autopilot.emulators.bamf import BamfWindow
00014 from autopilot.matchers import Eventually
00015 from autopilot.testcase import AutopilotTestCase
00016 from dbus import DBusException
00017 from logging import getLogger
00018 import os
00019 from tempfile import mktemp
00020 from testtools.content import text_content
00021 from testtools.matchers import Equals
00022 
00023 from unity.emulators.dash import Dash
00024 from unity.emulators.hud import Hud
00025 from unity.emulators.launcher import LauncherController
00026 from unity.emulators.panel import PanelController
00027 from unity.emulators.switcher import Switcher
00028 from unity.emulators.window_manager import WindowManager
00029 from unity.emulators.workspace import WorkspaceManager
00030 from unity.emulators.unity import (
00031     set_log_severity,
00032     start_log_to_file,
00033     reset_logging,
00034     )
00035 
00036 
00037 log = getLogger(__name__)
00038 
00039 
00040 class UnityTestCase(AutopilotTestCase):
00041     """Unity test case base class, with improvments specific to Unity tests."""
00042 
00043     def __init__(self, *args):
00044         super(UnityTestCase, self).__init__(*args)
00045 
00046     def setUp(self):
00047         super(UnityTestCase, self).setUp()
00048         self._setUpUnityLogging()
00049         self._initial_workspace_num = self.workspace.current_workspace
00050         self.addCleanup(self.check_test_behavior)
00051         #
00052         # Setting this here since the show desktop feature seems to be a bit
00053         # ropey. Once it's been proven to work reliably we can remove this line:
00054         self.set_unity_log_level("unity.plugin", "DEBUG")
00055 
00056     def check_test_behavior(self):
00057         """Fail the test if it did something naughty.
00058 
00059         This includes leaving the dash or the hud open, changing the current
00060         workspace, or leaving the system in show_desktop mode.
00061 
00062         """
00063         well_behaved = True
00064         reasons = []
00065         log.info("Checking system state for badly behaving test...")
00066 
00067         # Have we switched workspace?
00068         if self.workspace.current_workspace != self._initial_workspace_num:
00069             well_behaved = False
00070             reasons.append("The test changed the active workspace from %d to %d." \
00071                 % (self._initial_workspace_num, self.workspace.current_workspace))
00072             log.warning("Test changed the active workspace, changing it back...")
00073             self.workspace.switch_to(self._initial_workspace_num)
00074         # Have we left the dash open?
00075         if self.dash.visible:
00076             well_behaved = False
00077             reasons.append("The test left the dash open.")
00078             log.warning("Test left the dash open, closing it...")
00079             self.dash.ensure_hidden()
00080         # ... or the hud?
00081         if self.hud.visible:
00082             well_behaved = False
00083             reasons.append("The test left the hud open.")
00084             log.warning("Test left the hud open, closing it...")
00085             self.hud.ensure_hidden()
00086         # Are we in show desktop mode?
00087         if self.window_manager.showdesktop_active:
00088             well_behaved = False
00089             reasons.append("The test left the system in show_desktop mode.")
00090             log.warning("Test left the system in show desktop mode, exiting it...")
00091             self.window_manager.leave_show_desktop()
00092         for launcher in self.launcher.get_launchers():
00093             if launcher.in_keynav_mode:
00094                 well_behaved = False
00095                 reasons.append("The test left the launcher keynav mode enabled.")
00096                 log.warning("Test left the launcher in keynav mode, exiting it...")
00097                 launcher.key_nav_cancel()
00098             if launcher.in_switcher_mode:
00099                 well_behaved = False
00100                 reasons.append("The test left the launcher in switcher mode.")
00101                 log.warning("Test left the launcher in switcher mode, exiting it...")
00102                 launcher.switcher_cancel()
00103 
00104         if not well_behaved:
00105             self.fail("/n".join(reasons))
00106         else:
00107             log.info("Test was well behaved.")
00108 
00109     @property
00110     def dash(self):
00111         if not getattr(self, '__dash', None):
00112             self.__dash = Dash()
00113         return self.__dash
00114 
00115     @property
00116     def hud(self):
00117         if not getattr(self, '__hud', None):
00118             self.__hud = Hud();
00119         return self.__hud
00120 
00121     @property
00122     def launcher(self):
00123         if not getattr(self, '__launcher', None):
00124             self.__launcher = self._get_launcher_controller()
00125         return self.__launcher
00126 
00127     @property
00128     def panels(self):
00129         if not getattr(self, '__panels', None):
00130             self.__panels = self._get_panel_controller()
00131         return self.__panels
00132 
00133     @property
00134     def switcher(self):
00135         if not getattr(self, '__switcher', None):
00136             self.__switcher = Switcher()
00137         return self.__switcher
00138 
00139     @property
00140     def window_manager(self):
00141         if not getattr(self, '__window_manager', None):
00142             self.__window_manager = self._get_window_manager()
00143         return self.__window_manager
00144 
00145     @property
00146     def workspace(self):
00147         if not getattr(self, '__workspace', None):
00148             self.__workspace = WorkspaceManager()
00149         return self.__workspace
00150 
00151     def _get_launcher_controller(self):
00152         controllers = LauncherController.get_all_instances()
00153         self.assertThat(len(controllers), Equals(1))
00154         return controllers[0]
00155 
00156     def _get_panel_controller(self):
00157         controllers = PanelController.get_all_instances()
00158         self.assertThat(len(controllers), Equals(1))
00159         return controllers[0]
00160 
00161     def _get_window_manager(self):
00162         managers = WindowManager.get_all_instances()
00163         self.assertThat(len(managers), Equals(1))
00164         return managers[0]
00165 
00166     def _setUpUnityLogging(self):
00167         self._unity_log_file_name = mktemp(prefix=self.shortDescription())
00168         start_log_to_file(self._unity_log_file_name)
00169         self.addCleanup(self._tearDownUnityLogging)
00170 
00171     def _tearDownUnityLogging(self):
00172         # If unity dies, our dbus interface has gone, and reset_logging will fail
00173         # but we still want our log, so we ignore any errors.
00174         try:
00175             reset_logging()
00176         except DBusException:
00177             pass
00178         with open(self._unity_log_file_name) as unity_log:
00179             self.addDetail('unity-log', text_content(unity_log.read()))
00180         os.remove(self._unity_log_file_name)
00181         self._unity_log_file_name = ""
00182 
00183     def set_unity_log_level(self, component, level):
00184         """Set the unity log level for 'component' to 'level'.
00185 
00186         Valid levels are: TRACE, DEBUG, INFO, WARNING and ERROR.
00187 
00188         Components are dotted unity component names. The empty string specifies
00189         the root logging component.
00190         """
00191         valid_levels = ('TRACE', 'DEBUG', 'INFO', 'WARN', 'WARNING', 'ERROR')
00192         if level not in valid_levels:
00193             raise ValueError("Log level '%s' must be one of: %r" % (level, valid_levels))
00194         set_log_severity(component, level)
00195 
00196     def assertNumberWinsIsEventually(self, app, num):
00197         """Asserts that 'app' eventually has 'num' wins. Waits up to 10 seconds."""
00198 
00199         self.assertThat(lambda: len(app.get_windows()), Eventually(Equals(num)))