예제 #1
0
    def test_start_new_if_always_start_new(self):
        service = FakeService()
        service.always_start_new = True
        options = Options(network=Network(name='the-network',
                                          id='the-network-id'),
                          timeout=1,
                          remove=True,
                          run_dir='/etc',
                          build=[])
        agent = ServiceAgent(service, options, None)
        restarted = False

        def start():
            nonlocal restarted
            restarted = True

        self.docker._existing_containers = [
            Bunch(status='exited',
                  start=start,
                  network='the-network',
                  attrs={'Config': {
                      'Env': []
                  }},
                  name="{}-testing-123".format(service.name))
        ]
        agent.run_image()
        assert len(self.docker._services_started) == 1
        assert not restarted
예제 #2
0
 def test_action_property(self):
     service = Bunch(name='service1', dependencies=[], dependants=[])
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     assert agent.action is None
     with pytest.raises(ServiceAgentException):
         agent.action = 'blah'
     agent.action = 'start'
     assert agent.action == 'start'
예제 #3
0
 def test_fail_if_action_not_set(self):
     service = Bunch(name='service1', dependencies=[], dependants=[])
     fake_context = FakeRunningContext()
     agent = ServiceAgent(service, DEFAULT_OPTIONS, fake_context)
     with pytest.raises(ServiceAgentException):
         agent.run()
     assert len(fake_context.failed_services) == 1
     assert fake_context.failed_services[0] is service
예제 #4
0
 def test_can_stop(self):
     services = connect_services([
         Bunch(name='service1', dependencies=[]),
         Bunch(name='service2', dependencies=['service1'])
     ])
     agent = ServiceAgent(services['service1'], DEFAULT_OPTIONS, None)
     assert agent.can_stop is False
     agent.process_service_stopped(services['service2'])
     assert agent.can_stop is True
예제 #5
0
 def test_run_image(self):
     agent = ServiceAgent(FakeService(), DEFAULT_OPTIONS, None)
     agent.run_image()
     assert len(self.docker._services_started) == 1
     prefix, service, network = self.docker._services_started[0]
     assert prefix == "service1-testing"
     assert service.name == 'service1'
     assert service.image == 'not/used'
     assert network.name == 'the-network'
예제 #6
0
 def test_build_image_dockerfile(self):
     fake_service = FakeService(name='myservice')
     fake_service.dockerfile = 'Dockerfile.other'
     fake_service.build_from = "the/service/dir"
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS,
                          FakeRunningContext())
     agent.build_image()
     assert len(self.docker._images_built) == 1
     _, dockerfile, _ = self.docker._images_built[0]
     assert dockerfile == 'Dockerfile.other'
예제 #7
0
 def test_run_image_extrapolate_env(self):
     service = FakeService()
     service.env = {'ENV_ONE': 'http://{host}:{port:d}'}
     context.Context['host'] = 'zombo.com'
     context.Context['port'] = 80
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     agent.run_image()
     assert len(self.docker._services_started) == 1
     _, service, _ = self.docker._services_started[0]
     assert service.env['ENV_ONE'] == 'http://zombo.com:80'
예제 #8
0
 def test_can_start(self):
     services = connect_services([
         Bunch(name='service1', dependencies=[]),
         Bunch(name='service2', dependencies=['service1'])
     ])
     agent = ServiceAgent(services['service2'], DEFAULT_OPTIONS, None)
     assert agent.can_start is False
     agent.process_service_started(services['service1'])
     assert agent.can_start is True
     agent.status = AgentStatus.IN_PROGRESS
     assert agent.can_start is False
예제 #9
0
 def test_build_image(self, mock_datetime):
     now = datetime.now()
     mock_datetime.now.return_value = now
     fake_service = FakeService(name='myservice')
     fake_service.build_from = "the/service/dir"
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS,
                          FakeRunningContext())
     retval = agent.build_image()
     assert len(self.docker._images_built) == 1
     build_dir, dockerfile, image_tag = self.docker._images_built[0]
     assert build_dir == "/etc/the/service/dir"
     assert dockerfile == 'Dockerfile'
     assert image_tag == now.strftime("myservice-%Y-%m-%d-%H%M")
     assert retval == image_tag
     assert RunCondition.BUILD_IMAGE in agent.run_condition.actions
예제 #10
0
 def test_skip_if_running_on_same_network(self):
     service = FakeService()
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     self.docker._existing_containers = [
         Bunch(status='running',
               name="{}-testing-123".format(service.name),
               network='the-network')
     ]
     agent.run_image()
     assert len(self.docker._services_started) == 0
     assert len(self.docker._existing_queried) == 1
     assert self.docker._existing_queried[0] == ("service1-testing",
                                                 Network(
                                                     name="the-network",
                                                     id="the-network-id"))
예제 #11
0
 def test_start_existing_if_differing_env_value_type_but_not_string(self):
     service = FakeService()
     service.env = {'KEY': 12345}
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     self.docker._existing_containers = [
         Bunch(status='exited',
               network='the-network',
               id='longass-container-id',
               image=Bunch(tags=[service.image]),
               attrs={'Config': {
                   'Env': ['KEY=12345']
               }},
               name="{}-testing-123".format(service.name))
     ]
     agent.run_image()
     assert len(self.docker._services_started) == 0
예제 #12
0
 def test_start_old_container_if_exists(self):
     service = FakeService()
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     self.docker._existing_containers = [
         Bunch(status='exited',
               network='the-network',
               id='longass-container-id',
               image=Bunch(tags=[service.image]),
               attrs={'Config': {
                   'Env': []
               }},
               name="{}-testing-123".format(service.name))
     ]
     agent.run_image()
     assert len(self.docker._services_started) == 0
     assert self.docker._containers_ran == ['longass-container-id']
예제 #13
0
 def __init__(self, services_by_name, options: Options):
     super().__init__()
     self.agent_set = {service: ServiceAgent(service, options, self)
                       for name, service in services_by_name.items()}
     self.failed_services = []
     self.processed_services = []
     self.service_pop_lock = threading.Lock()
예제 #14
0
 def test_start_new_container_if_old_has_different_tag(self):
     service = FakeService()
     agent = ServiceAgent(service, DEFAULT_OPTIONS, None)
     self.docker._existing_containers = [
         Bunch(status='exited',
               network='the-network',
               id='longass-container-id',
               image=Bunch(tags=['different-tag']),
               attrs={'Config': {
                   'Env': []
               }},
               name="{}-miniboss-123".format(service.name))
     ]
     agent.run_image()
     assert len(self.docker._services_started) == 1
     prefix, service, network = self.docker._services_started[0]
     assert prefix == "service1-testing"
     assert service.name == 'service1'
     assert service.image == 'not/used'
     assert network.name == 'the-network'
     assert self.docker._containers_ran == []
예제 #15
0
 def test_stop_container_does_not_exist(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService(exception_at_init=ValueError)
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.stop_service()
     agent.join()
     assert agent.status == AgentStatus.STOPPED
예제 #16
0
    def test_stop_remove_container_on_failed(self):
        fake_context = FakeRunningContext()
        name = 'aservice'
        container = FakeContainer(name='{}-testing-5678'.format(name),
                                  network='the-network',
                                  status='running')
        _context = self

        class CrazyFakeService(FakeService):
            def ping(self):
                _context.docker._existing_containers = [container]
                raise ValueError("Blah")

        options = Options(network=Network(name='the-network',
                                          id='the-network-id'),
                          timeout=0.01,
                          remove=True,
                          run_dir='/etc',
                          build=[])
        agent = ServiceAgent(CrazyFakeService(name=name), options,
                             fake_context)
        agent.start_service()
        agent.join()
        assert container.stopped
        assert container.removed_at is not None
        # This is 0 because the service wasn't stopped by the user
        assert len(fake_context.stopped_services) == 0
예제 #17
0
 def test_pre_start_before_run(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService()
     assert not fake_service.pre_start_called
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.start_service()
     agent.join()
     assert fake_service.pre_start_called
예제 #18
0
 def test_build_on_start(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService()
     fake_service.build_from = "the/service/dir"
     options = attr.evolve(DEFAULT_OPTIONS, build=[fake_service.name])
     agent = ServiceAgent(fake_service, options, fake_context)
     agent.start_service()
     agent.join()
     assert len(self.docker._images_built) == 1
예제 #19
0
 def test_if_build_from_and_latest(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService()
     fake_service.image = "service:latest"
     fake_service.build_from = "the/service/dir"
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.start_service()
     agent.join()
     assert len(self.docker._images_built) == 1
예제 #20
0
 def test_ping_and_init_after_run(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService()
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.start_service()
     agent.join()
     assert len(fake_context.started_services) == 1
     assert fake_context.started_services[0].name == 'service1'
     assert fake_service.ping_count == 1
     assert fake_service.init_called
예제 #21
0
 def test_call_collection_failed_on_error(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService(exception_at_init=ValueError)
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.start_service()
     agent.join()
     assert fake_service.ping_count > 0
     assert fake_context.started_services == []
     assert len(fake_context.failed_services) == 1
     assert fake_context.failed_services[0].name == 'service1'
예제 #22
0
 def test_repeat_ping_and_timeout(self, mock_time):
     mock_time.monotonic.side_effect = [0, 0.2, 0.6, 0.8, 1]
     fake_context = FakeRunningContext()
     fake_service = FakeService(fail_ping=True)
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.start_service()
     agent.join()
     assert fake_service.ping_count == 3
     assert mock_time.sleep.call_count == 3
     assert agent.status == AgentStatus.FAILED
     assert len(fake_context.failed_services) == 1
     assert fake_context.failed_services[0] is fake_service
예제 #23
0
 def test_stop_existing_container(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService(exception_at_init=ValueError)
     container = FakeContainer(name='{}-testing-5678'.format(
         fake_service.name),
                               network='the-network',
                               status='running')
     self.docker._existing_containers = [container]
     agent = ServiceAgent(fake_service, DEFAULT_OPTIONS, fake_context)
     agent.stop_service()
     agent.join()
     assert agent.status == AgentStatus.STOPPED
     assert container.stopped
     assert len(fake_context.stopped_services) == 1
     assert fake_context.stopped_services[0] is fake_service
예제 #24
0
 def test_service_failed_on_failed_ping(self):
     fake_context = FakeRunningContext()
     fake_service = FakeService(fail_ping=True)
     # Using options with low timeout so that test doesn't hang
     options = Options(network=Network(name='the-network',
                                       id='the-network-id'),
                       timeout=0.1,
                       remove=True,
                       run_dir='/etc',
                       build=[])
     agent = ServiceAgent(fake_service, options, fake_context)
     agent.start_service()
     agent.join()
     assert fake_service.ping_count > 0
     assert fake_context.started_services == []
     assert len(fake_context.failed_services) == 1
     assert fake_context.failed_services[0].name == 'service1'
예제 #25
0
 def test_yes_ping_no_init_if_started(self):
     service = FakeService()
     fake_context = FakeRunningContext()
     agent = ServiceAgent(service, DEFAULT_OPTIONS, fake_context)
     self.docker._existing_containers = [
         Bunch(status='exited',
               network='the-network',
               id='longass-container-id',
               image=Bunch(tags=[service.image]),
               attrs={'Config': {
                   'Env': []
               }},
               name="{}-testing-123".format(service.name))
     ]
     agent.start_service()
     agent.join()
     assert service.ping_count == 1
     assert not service.init_called
     assert self.docker._containers_ran == ['longass-container-id']
예제 #26
0
 def test_no_pre_ping_or_init_if_running(self):
     service = FakeService()
     fake_context = FakeRunningContext()
     options = Options(network=Network(name='the-network',
                                       id='the-network-id'),
                       timeout=1,
                       remove=True,
                       run_dir='/etc',
                       build=[])
     agent = ServiceAgent(service, options, fake_context)
     self.docker._existing_containers = [
         Bunch(status='running',
               network='the-network',
               name="{}-testing-123".format(service.name))
     ]
     agent.start_service()
     agent.join()
     assert service.ping_count == 0
     assert not service.init_called
     assert not service.pre_start_called