def test_change_error(self): change = pebble.Change( id=pebble.ChangeID('1234'), kind='start', summary='Start service "foo"', status='Done', tasks=[], ready=True, err=None, spawn_time=datetime.datetime.now(), ready_time=datetime.datetime.now(), ) error = pebble.ChangeError('Some error', change) self.assertIsInstance(error, pebble.Error) self.assertEqual(error.err, 'Some error') self.assertEqual(error.change, change) self.assertEqual(str(error), 'Some error')
def start_services( self, services: typing.List[str], timeout: float = 30.0, delay: float = 0.1, ) -> pebble.ChangeID: # A common mistake is to pass just the name of a service, rather than a list of services, # so trap that so it is caught quickly. if isinstance(services, str): raise TypeError( 'start_services should take a list of names, not just "{}"'. format(services)) # Note: jam 2021-04-20 We don't implement ChangeID, but the default caller of this is # Container.start() which currently ignores the return value known_services = self._render_services() # Names appear to be validated before any are activated, so do two passes for name in services: if name not in known_services: # TODO: jam 2021-04-20 This needs a better error type raise RuntimeError( '400 Bad Request: service "{}" does not exist'.format( name)) current = self._service_status.get(name, pebble.ServiceStatus.INACTIVE) if current == pebble.ServiceStatus.ACTIVE: # TODO: jam 2021-04-20 I believe pebble actually validates all the service names # can be started before starting any, and gives a list of things that couldn't # be done, but this is good enough for now raise pebble.ChangeError( '''\ cannot perform the following tasks: - Start service "{}" (service "{}" was previously started) '''.format(name, name), change=1234) # the change id is not respected for name in services: # If you try to start a service which is started, you get a ChangeError: # $ PYTHONPATH=. python3 ./test/pebble_cli.py start serv # ChangeError: cannot perform the following tasks: # - Start service "serv" (service "serv" was previously started) self._service_status[name] = pebble.ServiceStatus.ACTIVE
def stop_services( self, services: typing.List[str], timeout: float = 30.0, delay: float = 0.1, ) -> pebble.ChangeID: # handle a common mistake of passing just a name rather than a list of names if isinstance(services, str): raise TypeError( 'stop_services should take a list of names, not just "{}"'. format(services)) # TODO: handle invalid names # Note: jam 2021-04-20 We don't implement ChangeID, but the default caller of this is # Container.stop() which currently ignores the return value known_services = self._render_services() for name in services: if name not in known_services: # TODO: jam 2021-04-20 This needs a better error type # 400 Bad Request: service "bal" does not exist raise RuntimeError( '400 Bad Request: service "{}" does not exist'.format( name)) current = self._service_status.get(name, pebble.ServiceStatus.INACTIVE) if current != pebble.ServiceStatus.ACTIVE: # TODO: jam 2021-04-20 I believe pebble actually validates all the service names # can be started before starting any, and gives a list of things that couldn't # be done, but this is good enough for now raise pebble.ChangeError( '''\ ChangeError: cannot perform the following tasks: - Stop service "{}" (service "{}" is not active) '''.format(name, name), change=1234) # the change id is not respected for name in services: self._service_status[name] = pebble.ServiceStatus.INACTIVE