Unity 8
test_upstart.py
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 #
3 # Unity Autopilot Test Suite
4 # Copyright (C) 2013, 2014 Canonical
5 #
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
18 #
19 
20 """Tests for upstart integration."""
21 
22 import os
23 import stat
24 import signal
25 import subprocess
26 import time
27 
28 import fixtures
29 from testtools.matchers import Equals, MismatchError
30 from autopilot.matchers import Eventually
31 from autopilot.introspection import get_proxy_object_for_existing_process
32 
33 from unity8 import get_binary_path
34 from unity8.shell.emulators import UnityEmulatorBase
35 from unity8.shell.tests import UnityTestCase, _get_device_emulation_scenarios
36 
37 import logging
38 
39 logger = logging.getLogger(__name__)
40 
41 # from __future__ import range
42 # (python3's range, is same as python2's xrange)
43 import sys
44 if sys.version_info < (3,):
45  range = xrange
46 
47 
48 class UpstartIntegrationTests(UnityTestCase):
49 
50  scenarios = _get_device_emulation_scenarios()
51 
52  def _get_status(self):
53  pid, status = os.waitpid(
54  self.process.pid, os.WUNTRACED | os.WCONTINUED | os.WNOHANG)
55  logger.debug(
56  "Got status: {0}; stopped: {1}; continued: {2}".format(
57  status, os.WIFSTOPPED(status), os.WIFCONTINUED(status)))
58  return status
59 
60  def _launch_unity(self):
61  self.patch_environment("QT_LOAD_TESTABILITY", "1")
62 
63  try:
64  host_socket = os.getenv("MIR_SOCKET", "/run/mir_socket")
65  if stat.S_ISSOCK(os.stat(host_socket).st_mode):
66  self.patch_environment("MIR_SERVER_HOST_SOCKET",
67  host_socket)
68  socket = os.path.join(os.getenv("XDG_RUNTIME_DIR", "/tmp"),
69  "mir_socket")
70  self.patch_environment("MIR_SERVER_FILE", socket)
71  except OSError:
72  pass
73 
74  self.process = subprocess.Popen(
75  [get_binary_path()] + self.unity_geometry_args)
76 
77  def ensure_stopped():
78  self.process.terminate()
79  for i in range(10):
80  try:
81  self._get_status()
82  except OSError:
83  break
84  else:
85  time.sleep(1)
86  try:
87  self._get_status()
88  except OSError:
89  pass
90  else:
91  self.process.kill()
92 
93  self.process.wait()
94 
95  self.addCleanup(ensure_stopped)
96 
97  def _set_proxy(self):
98  super(UpstartIntegrationTests, self)._set_proxy(
99  get_proxy_object_for_existing_process(
100  pid=self.process.pid,
101  emulator_base=UnityEmulatorBase,))
102 
103  def test_no_sigstop(self):
104  self.useFixture(
105  fixtures.EnvironmentVariable(
106  'UNITY_MIR_EMITS_SIGSTOP', newvalue=None))
107  self._launch_unity()
108 
109  try:
110  self.assertThat(
111  lambda: os.WIFSTOPPED(self._get_status()),
112  Eventually(Equals(True)))
113  except MismatchError:
114  pass
115  else:
116  self.process.send_signal(signal.SIGCONT)
117  self.fail('Unity8 raised SIGSTOP')
118 
119  self._set_proxy()
120 
121  logger.debug("Unity started, waiting for it to be ready.")
122  self.wait_for_unity()
123  logger.debug("Unity loaded and ready.")
124 
125  def test_expect_sigstop(self):
126  self.useFixture(
127  fixtures.EnvironmentVariable('UNITY_MIR_EMITS_SIGSTOP', '1'))
128  self._launch_unity()
129  self.assertThat(
130  lambda: os.WIFSTOPPED(self._get_status()),
131  Eventually(Equals(True)), "Unity8 should raise SIGSTOP when ready")
132 
133  self.process.send_signal(signal.SIGCONT)
134  self.assertThat(
135  lambda: os.WIFCONTINUED(self._get_status()),
136  Eventually(Equals(True)), "Unity8 should have resumed")
137 
138  logger.debug("Unity started, waiting for it to be ready.")
139  self._set_proxy()
140  self.wait_for_unity()
141  logger.debug("Unity loaded and ready.")