Esempio n. 1
0
 def test_run_scripts_adds_data(self):
     scripts_dir = factory.make_name('scripts_dir')
     out_dir = os.path.join(scripts_dir, 'out')
     self.patch(maas_run_remote_scripts, 'install_dependencies')
     self.patch(maas_run_remote_scripts, 'run_script')
     url = factory.make_url()
     creds = factory.make_name('creds')
     script = make_script(scripts_dir=scripts_dir)
     script.pop('result', None)
     script.pop('combined', None)
     script.pop('stderr', None)
     script.pop('stdout', None)
     script['args'] = {
         'url': url,
         'creds': creds,
         'script_result_id': script['script_result_id'],
         'script_version_id': script['script_version_id'],
     }
     scripts = [{
         'name': script['name'],
         'path': script['path'],
         'script_result_id': script['script_result_id'],
         'script_version_id': script['script_version_id'],
         'timeout_seconds': script['timeout_seconds'],
         'parallel': script['parallel'],
         'hardware_type': script['hardware_type'],
         'has_started': script['has_started'],
     }]
     run_scripts(url, creds, scripts_dir, out_dir, scripts)
     scripts[0].pop('thread', None)
     self.assertDictEqual(script, scripts[0])
Esempio n. 2
0
    def test_run_scripts(self):
        mock_install_deps = self.patch(
            maas_run_remote_scripts, 'install_dependencies')
        mock_run_script = self.patch(maas_run_remote_scripts, 'run_script')
        single_thread = make_scripts(instance=False, parallel=0)
        instance_thread = [
            make_scripts(parallel=1)
            for _ in range(3)
        ]
        any_thread = make_scripts(instance=False, parallel=2)
        scripts = copy.deepcopy(single_thread)
        for instance_thread_group in instance_thread:
            scripts += copy.deepcopy(instance_thread_group)
        scripts += copy.deepcopy(any_thread)
        url = factory.make_url()
        creds = factory.make_name('creds')
        scripts_dir = factory.make_name('scripts_dir')
        out_dir = os.path.join(scripts_dir, 'out')

        run_scripts(url, creds, scripts_dir, out_dir, scripts)

        self.assertEquals(
            len(single_thread) + len(instance_thread) + len(any_thread),
            mock_install_deps.call_count)

        expected_calls = [
            call(script=script, scripts_dir=scripts_dir, send_result=True)
            for script in sorted(scripts, key=lambda i: (
                99 if i['hardware_type'] == 0 else i['hardware_type'],
                i['name']))
            if script['parallel'] != 2
        ]
        expected_calls += [
            call(script=script, scripts_dir=scripts_dir, send_result=True)
            for script in sorted(scripts, key=lambda i: (
                len(i.get('packages', {}).keys()), i['name']))
            if script['parallel'] == 2
        ]
        self.assertThat(mock_run_script, MockCallsMatch(*expected_calls))
    def test_run_scripts_signals_failure(self):
        scripts_dir = self.useFixture(TempDirectory()).path
        mock_signal = self.patch(maas_run_remote_scripts, 'signal')
        self.patch(maas_run_remote_scripts, 'Popen')
        self.patch(maas_run_remote_scripts, 'capture_script_output')
        scripts = self.make_scripts()
        self.make_script_output(scripts, scripts_dir)

        # Don't need to give the url or creds as we're not running the scripts
        # and sending the result. The scripts_dir and out_dir are the same as
        # in the test environment there isn't anything in the scripts_dir.
        # Returns one due to mock_run.returncode returning a MagicMock which is
        # detected as a failed script run.
        self.assertEquals(
            1, run_scripts(None, None, scripts_dir, scripts_dir, scripts))

        self.assertThat(
            mock_signal,
            MockAnyCall(None, None, 'FAILED', '1 scripts failed to run'))
    def test_run_scripts_signals_timeout(self):
        scripts_dir = self.useFixture(TempDirectory()).path
        mock_signal = self.patch(maas_run_remote_scripts, 'signal')
        self.patch(maas_run_remote_scripts, 'Popen')
        scripts = self.make_scripts()
        self.make_script_output(scripts, scripts_dir)
        mock_cap = self.patch(maas_run_remote_scripts, 'capture_script_output')
        mock_cap.side_effect = TimeoutExpired(
            [factory.make_name('arg') for _ in range(3)],
            scripts[0]['timeout_seconds'])

        # Don't need to give the url or creds as we're not running the scripts
        # and sending the result. The scripts_dir and out_dir are the same as
        # in the test environment there isn't anything in the scripts_dir.
        self.assertEquals(
            1, run_scripts(None, None, scripts_dir, scripts_dir, scripts))

        self.assertThat(
            mock_signal,
            MockAnyCall(creds=None,
                        url=None,
                        status='TIMEDOUT',
                        error='Timeout(%s) expired on %s [1/1]' %
                        (str(timedelta(seconds=scripts[0]['timeout_seconds'])),
                         scripts[0]['name']),
                        script_result_id=scripts[0]['script_result_id'],
                        script_version_id=scripts[0]['script_version_id'],
                        files={
                            scripts[0]['name']: scripts[0]['output'],
                            '%s.out' % scripts[0]['name']:
                            scripts[0]['stdout'],
                            '%s.err' % scripts[0]['name']:
                            scripts[0]['stderr'],
                        }))
        self.assertThat(
            mock_signal,
            MockAnyCall(None, None, 'FAILED', '1 scripts failed to run'))
    def test_run_scripts_signals_failure_on_unexecutable_script_baderrno(self):
        # Regression test for LP:1669246
        scripts_dir = self.useFixture(TempDirectory()).path
        mock_signal = self.patch(maas_run_remote_scripts, 'signal')
        mock_popen = self.patch(maas_run_remote_scripts, 'Popen')
        mock_popen.side_effect = OSError(0, 'Exec format error')
        self.patch(maas_run_remote_scripts, 'capture_script_output')
        scripts = self.make_scripts()
        script = scripts[0]
        self.make_script_output(scripts, scripts_dir)

        # Don't need to give the url or creds as we're not running the scripts
        # and sending the result. The scripts_dir and out_dir are the same as
        # in the test environment there isn't anything in the scripts_dir.
        # Returns one due to mock_run.returncode returning a MagicMock which is
        # detected as a failed script run.
        self.assertEquals(
            1, run_scripts(None, None, scripts_dir, scripts_dir, scripts))

        self.assertThat(
            mock_signal,
            MockAnyCall(creds=None,
                        url=None,
                        status='WORKING',
                        exit_status=2,
                        error='Failed to execute %s [1/1]: 2' % script['name'],
                        script_result_id=script['script_result_id'],
                        script_version_id=script['script_version_id'],
                        files={
                            script['name']:
                            b'[Errno 0] Exec format error',
                            '%s.err' % script['name']:
                            b'[Errno 0] Exec format error',
                        }))
        self.assertThat(
            mock_signal,
            MockAnyCall(None, None, 'FAILED', '1 scripts failed to run'))
    def test_run_scripts(self):
        scripts_dir = self.useFixture(TempDirectory()).path
        mock_signal = self.patch(maas_run_remote_scripts, 'signal')
        mock_popen = self.patch(maas_run_remote_scripts, 'Popen')
        mock_capture_script_output = self.patch(maas_run_remote_scripts,
                                                'capture_script_output')
        scripts = self.make_scripts()
        self.make_script_output(scripts, scripts_dir)

        # Don't need to give the url or creds as we're not running the scripts
        # and sending the result. The scripts_dir and out_dir are the same as
        # in the test environment there isn't anything in the scripts_dir.
        # Returns one due to mock_run.returncode returning a MagicMock which is
        # detected as a failed script run.
        self.assertEquals(
            1, run_scripts(None, None, scripts_dir, scripts_dir, scripts))

        args = {
            'url': None,
            'creds': None,
            'status': 'WORKING',
            'script_result_id': scripts[0]['script_result_id'],
            'script_version_id': scripts[0]['script_version_id'],
            'error': 'Starting %s [1/1]' % scripts[0]['name'],
        }
        self.assertThat(mock_signal, MockAnyCall(**args))
        self.assertThat(mock_popen, MockCalledOnce())
        self.assertThat(mock_capture_script_output, MockCalledOnce())
        # This is a MagicMock
        args['exit_status'] = ANY
        args['files'] = {
            scripts[0]['name']: scripts[0]['output'],
            '%s.out' % scripts[0]['name']: scripts[0]['stdout'],
            '%s.err' % scripts[0]['name']: scripts[0]['stderr'],
        }
        args['error'] = 'Finished %s [1/1]: 1' % scripts[0]['name']
        self.assertThat(mock_signal, MockAnyCall(**args))