• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
5"""
6Provides utility class for stopping and restarting services
7
8When using this class, one likely wishes to do the following:
9
10    def initialize(self):
11        self._services = service_stopper.ServiceStopper(['service'])
12        self._services.stop_services()
13
14
15    def cleanup(self):
16        self._services.start_services()
17
18As this ensures that the services will be off before the test code runs, and
19the test framework will ensure that the services are restarted through any
20code path out of the test.
21"""
22
23import logging
24
25from autotest_lib.client.bin import utils
26from autotest_lib.client.common_lib import error
27
28
29class ServiceStopper(object):
30    """Class to manage CrOS services.
31    Public attributes:
32      services_to_stop: list of services that should be stopped
33
34   Public constants:
35      POWER_DRAW_SERVICES: list of services that influence power test in
36    unpredictable/undesirable manners.
37
38    Public methods:
39      stop_sevices: stop running system services.
40      restore_services: restore services that were previously stopped.
41
42    Private attributes:
43      _services_stopped: list of services that were successfully stopped
44    """
45
46    POWER_DRAW_SERVICES = ['powerd', 'update-engine', 'vnc']
47
48    # List of thermal throttling services that should be disabled.
49    # - temp_metrics for link.
50    # - thermal for daisy, snow, pit etc.
51    # - dptf for intel >= baytrail
52    # TODO(ihf): cpu_quiet on nyan isn't a service. We still need to disable it
53    #            on nyan. See crbug.com/357457.
54    THERMAL_SERVICES = ['dptf', 'temp_metrics', 'thermal']
55
56    def __init__(self, services_to_stop=[]):
57        """Initialize instance of class.
58
59        By Default sets an empty list of services.
60        """
61        self.services_to_stop = services_to_stop
62        self._services_stopped = []
63
64
65    def stop_services(self):
66        """Turn off managed services."""
67
68        for service in self.services_to_stop:
69            cmd = 'status %s' % service
70            out = utils.system_output(cmd, ignore_status=True)
71            is_stopped = 'start/running' not in out
72            if is_stopped:
73                continue
74            try:
75                utils.system('stop %s' % service)
76                self._services_stopped.append(service)
77            except error.CmdError as e:
78                logging.warning('Error stopping service %s. %s',
79                                service, str(e))
80
81
82    def restore_services(self):
83        """Restore services that were stopped."""
84        for service in reversed(self._services_stopped):
85            utils.system('start %s' % service, ignore_status=True)
86        self._services_stopped = []
87
88
89    def __enter__(self):
90        self.stop_services()
91        return self
92
93
94    def __exit__(self, exnval, exntype, exnstack):
95        self.restore_services()
96
97
98    def close(self):
99        """Equivalent to restore_services."""
100        self.restore_services()
101
102
103def get_thermal_service_stopper():
104    """Convenience method to retrieve thermal service stopper."""
105    return ServiceStopper(services_to_stop=ServiceStopper.THERMAL_SERVICES)
106