def test_shove_instances(self):
        instance1 = ShoveInstanceFactory.create(hostname='foo', active=True)
        instance2 = ShoveInstanceFactory.create(hostname='bar', active=True)
        ShoveInstanceFactory.create(hostname='baz', active=False)

        command = ScheduledCommandFactory(hostnames='foo,bar,baz')
        assert_equal(set(command.shove_instances), set([instance1, instance2]))
    def test_run(self):
        instance1 = ShoveInstanceFactory.create(hostname='foo', active=True)
        instance2 = ShoveInstanceFactory.create(hostname='bar', active=True)
        command = ScheduledCommandFactory(command='asdf', hostnames='foo,bar')
        command.project.send_command = Mock()

        with patch('captain.projects.models.timezone') as mock_timezone:
            now =  aware_datetime(2014, 1, 1, 1, 1, 1)
            mock_timezone.now.return_value = now
            command.run()

        assert_equal(command.last_run, now)
        command.project.send_command.assert_called_with(None, 'asdf',
                                                        CONTAINS(instance1, instance2))
示例#3
0
    def test_clean_hostnames(self):
        """
        The cleaned hostname value should be a comma-separated list of
        hostnames of the selected ShoveInstances.
        """
        project = ProjectFactory.create()
        instance1 = ShoveInstanceFactory.create(hostname='foo.bar')
        instance2 = ShoveInstanceFactory.create(hostname='baz.biff')
        project.shove_instances.add(instance1)
        project.shove_instances.add(instance2)

        form = CreateScheduledCommandForm({
            'command': 'test',
            'hostnames': [instance1.pk, instance2.pk],
        }, project=project)
        form.is_valid()
        hostnames = form.cleaned_data['hostnames'].split(',')
        assert_equal(set(hostnames), set(['foo.bar', 'baz.biff']))
    def test_inactive_thread_mark_inactive_shoves(self):
        """
        mark_inactive_shoves should find any ShoveInstances with a
        last_heartbeat older than the HEARTBEAT_INACTIVE_DELAY setting
        and mark them as inactive.
        """
        up_to_date_instance = ShoveInstanceFactory.create(
            last_heartbeat=aware_datetime(2014, 1, 1, 10, 0, 0), active=True)
        out_of_date_instance = ShoveInstanceFactory.create(
            last_heartbeat=aware_datetime(2014, 1, 1, 9, 30, 0), active=True)

        thread = monitor_shove_instances.MarkInactiveShoveInstancesThread()
        with self.settings(HEARTBEAT_INACTIVE_DELAY=10*60):
            with patch.object(monitor_shove_instances, 'timezone') as mock_timezone:
                mock_timezone.now.return_value = aware_datetime(2014, 1, 1, 10, 5, 0)
                thread.mark_inactive_shoves()

        assert_equal(ShoveInstance.objects.get(pk=up_to_date_instance.pk).active, True)
        assert_equal(ShoveInstance.objects.get(pk=out_of_date_instance.pk).active, False)
    def test_send_command(self):
        project = ProjectFactory.create(project_name='myproject')
        instance = ShoveInstanceFactory.create(active=True, routing_key='route')
        project.shove_instances.add(instance)
        sent_command = SentCommandFactory.create(command='asdf')

        with patch('captain.projects.models.shove') as shove:
            log = instance.send_command(project, sent_command)
            shove.send_command.assert_called_with('route', 'myproject', 'asdf', log.pk)
            assert_equal(log.shove_instance, instance)
            assert_equal(log.sent_command, sent_command)
示例#6
0
    def test_non_whitespace_command(self):
        """If a command has non-whitespace characters, the form should be valid."""
        project = ProjectFactory.create()
        shove_instance = ShoveInstanceFactory.create()
        project.shove_instances.add(shove_instance)

        form_data = {
            'command': '   whitespace but not blank   ',
            'shove_instances': [shove_instance.pk]
        }
        form = RunCommandForm(form_data, project=project)
        assert_true(form.is_valid())
    def test_handle_heartbeat_remove_projects(self):
        """Remove any old projects not in the project_names list."""
        instance = ShoveInstanceFactory.create(routing_key='asdf')
        project1 = ProjectFactory.create(project_name='foo')
        project2 = ProjectFactory.create(project_name='bar')
        instance.projects.add(project1)

        monitor_shove_instances.handle_heartbeat_event({
            'routing_key': 'asdf',
            'hostname': 'paranoia.local',
            'project_names': 'bar,baz',
        })

        instance = ShoveInstance.objects.get(routing_key='asdf')
        assert_equal(list(instance.projects.all()), [project2])
示例#8
0
    def test_valid_command(self, get_object):
        """
        If the user submits a valid command, send it to shove and redirect back to the project.
        """
        # Mock send_command on the project returned by get_object to inject it into the view.
        self.project.send_command = Mock()
        get_object.return_value = self.project

        instance1, instance2 = ShoveInstanceFactory.create_batch(2, active=True)
        self.project.shove_instances.add(instance1, instance2)

        user = self._login_user(True)
        response = self._run_command(command='blah', shove_instances=[instance1.pk, instance2.pk])
        self.assertRedirects(response, self.project.get_absolute_url())
        self.project.send_command.assert_called_once_with(user, 'blah',
                                                          CONTAINS(instance1, instance2))
    def test_handle_heartbeat_existing_shove_instance(self):
        """
        If a shove instance for the given routing key already exists,
        update it with the latest hostname and projects.
        """
        instance = ShoveInstanceFactory.create(routing_key='asdf', hostname='old.local')
        project1 = ProjectFactory.create(project_name='foo')

        monitor_shove_instances.handle_heartbeat_event({
            'routing_key': 'asdf',
            'hostname': 'paranoia.local',
            'project_names': 'foo',
        })
        instance = ShoveInstance.objects.get(pk=instance.pk)
        assert_equal(instance.hostname, 'paranoia.local')
        assert_equal(list(instance.projects.all()), [project1])
示例#10
0
    def test_send_command_no_user(self):
        """
        If None is passed in as the user, do not perform any permission checks and run the command.
        """
        project = ProjectFactory.create(project_name='blah')

        instance = ShoveInstanceFactory.create(active=True)
        project.shove_instances.add(instance)

        with patch.object(ShoveInstance, 'send_command', autospec=True) as send_command:
            sent_command = project.send_command(None, 'asdf', [instance])
            send_command.assert_called_with(instance, project, sent_command)

        assert_equal(sent_command.project, project)
        assert_equal(sent_command.user, None)
        assert_equal(sent_command.command, 'asdf')
示例#11
0
    def test_whitespace_command(self):
        """If a command consists only of whitespace, the form should be invalid."""
        project = ProjectFactory.create()
        shove_instance = ShoveInstanceFactory.create()
        project.shove_instances.add(shove_instance)

        form = RunCommandForm({'command': '     ', 'shove_instances': [shove_instance.pk]},
                              project=project)
        assert_false(form.is_valid())

        form = RunCommandForm({'command': '\t\t', 'shove_instances': [shove_instance.pk]},
                              project=project)
        assert_false(form.is_valid())

        form = RunCommandForm({'command': '\n\n\n\n', 'shove_instances': [shove_instance.pk]},
                              project=project)
        assert_false(form.is_valid())
示例#12
0
    def test_send_command_has_permission(self):
        """
        If the user has permission to run a command for this project,
        send the command to shove and create a sent command for it.
        """
        user = UserFactory.create()
        project = ProjectFactory.create(project_name='blah')
        assign_perm('can_run_commands', user, project)

        instance1, instance2 = ShoveInstanceFactory.create_batch(2, active=True)
        project.shove_instances.add(instance1, instance2)

        with patch.object(ShoveInstance, 'send_command', autospec=True) as send_command:
            sent_command = project.send_command(user, 'asdf', [instance1, instance2])
            send_command.assert_has_calls([call(instance1, project, sent_command),
                                           call(instance2, project, sent_command)],
                                          any_order=True)

        assert_equal(sent_command.project, project)
        assert_equal(sent_command.user, user)
        assert_equal(sent_command.command, 'asdf')
示例#13
0
    def test_send_command_inactive_shoves(self):
        """
        If any of the shove instances given are not in the set of active
        shove instances for this project, raise a ValueError.
        """
        user = UserFactory.create()
        project = ProjectFactory.create()
        assign_perm('can_run_commands', user, project)

        instance1, instance2 = ShoveInstanceFactory.create_batch(2, active=True)
        project.shove_instances.add(instance1)
        with assert_raises(ValueError):
            project.send_command(user, 'asdf', [instance1, instance2])

        # Now try with an inactive instance that is part of the
        # project's instances.
        instance2.active = False
        instance2.save()
        project.shove_instances.add(instance2)
        with assert_raises(ValueError):
            project.send_command(user, 'asdf', [instance1, instance2])
示例#14
0
 def setUp(self):
     self.project = ProjectFactory.create()
     self.shove_instances = ShoveInstanceFactory.create_batch(2)
     self.project.shove_instances.add(*self.shove_instances)
     self.url = reverse('projects.details.schedule', args=(self.project.pk,))