Exemple #1
0
    def wait_for_minion_connections(self, targets, timeout):
        sys.stdout.write(
            ' {LIGHT_BLUE}*{ENDC} Waiting at most {0} for minions({1}) to '
            'connect back\n'.format(
                (timeout > 60 and
                 timedelta(seconds=timeout) or
                 '{0} secs'.format(timeout)),
                ', '.join(targets),
                **self.colors
            )
        )
        sys.stdout.flush()
        expected_connections = set(targets)
        now = datetime.now()
        expire = now + timedelta(seconds=timeout)
        while now <= expire:
            sys.stdout.write('\r' + ' ' * PNUM + '\r')
            sys.stdout.write(
                ' * {YELLOW}[Quit in {0}]{ENDC} Waiting for {1}'.format(
                    '{0}'.format(expire - now).rsplit('.', 1)[0],
                    ', '.join(expected_connections),
                    **self.colors
                )
            )
            sys.stdout.flush()

            responses = self.client.cmd(
                list(expected_connections), 'test.ping', expr_form='list',
            )
            for target in responses:
                if target not in expected_connections:
                    # Someone(minion) else "listening"?
                    continue
                expected_connections.remove(target)
                sys.stdout.write('\r' + ' ' * PNUM + '\r')
                sys.stdout.write(
                    '   {LIGHT_GREEN}*{ENDC} {0} connected.\n'.format(
                        target, **self.colors
                    )
                )
                sys.stdout.flush()

            if not expected_connections:
                return

            time.sleep(1)
            now = datetime.now()
        else:
            print(
                '\n {RED_BOLD}*{ENDC} WARNING: Minions failed to connect '
                'back. Tests requiring them WILL fail'.format(**self.colors)
            )
            print_header('=', sep='=', inline=True)
            raise SystemExit()
Exemple #2
0
    def run_integration_tests(self):
        '''
        Execute the integration tests suite
        '''
        named_tests = []
        named_unit_test = []

        if self.options.name:
            for test in self.options.name:
                if test.startswith('unit.'):
                    named_unit_test.append(test)
                    continue
                named_tests.append(test)

        if (self.options.unit or named_unit_test) and not named_tests and not \
                self._check_enabled_suites(include_cloud_provider=True):
            # We're either not running any integration test suites, or we're
            # only running unit tests by passing --unit or by passing only
            # `unit.<whatever>` to --name.  We don't need the tests daemon
            # running
            return [True]
        if not salt.utils.is_windows():
            self.prep_filehandles()

        try:
            print_header(
                ' * Setting up Salt daemons to execute tests',
                top=False, width=getattr(self.options, 'output_columns', PNUM)
            )
        except TypeError:
            print_header(' * Setting up Salt daemons to execute tests', top=False)

        status = []
        # Return an empty status if no tests have been enabled
        if not self._check_enabled_suites(include_cloud_provider=True) and not self.options.name:
            return status

        with TestDaemon(self):
            if self.options.name:
                for name in self.options.name:
                    if name.startswith('unit.'):
                        continue
                    results = self.run_suite('', name, load_from_name=True)
                    status.append(results)
            for suite in TEST_SUITES:
                if suite != 'unit' and getattr(self.options, suite):
                    status.append(self.run_integration_suite(**TEST_SUITES[suite]))
        return status
Exemple #3
0
    def wait_for_minion_connections(self, targets, timeout):
        sys.stdout.write(
            ' {LIGHT_BLUE}*{ENDC} Waiting at most {0} for minions({1}) to '
            'connect back\n'.format(
                (timeout > 60 and timedelta(seconds=timeout)
                 or '{0} secs'.format(timeout)), ', '.join(targets),
                **self.colors))
        sys.stdout.flush()
        expected_connections = set(targets)
        now = datetime.now()
        expire = now + timedelta(seconds=timeout)
        while now <= expire:
            sys.stdout.write('\r' + ' ' * PNUM + '\r')
            sys.stdout.write(
                ' * {YELLOW}[Quit in {0}]{ENDC} Waiting for {1}'.format(
                    '{0}'.format(expire - now).rsplit('.', 1)[0],
                    ', '.join(expected_connections), **self.colors))
            sys.stdout.flush()

            responses = self.client.cmd(
                list(expected_connections),
                'test.ping',
                expr_form='list',
            )
            for target in responses:
                if target not in expected_connections:
                    # Someone(minion) else "listening"?
                    continue
                expected_connections.remove(target)
                sys.stdout.write('\r' + ' ' * PNUM + '\r')
                sys.stdout.write(
                    '   {LIGHT_GREEN}*{ENDC} {0} connected.\n'.format(
                        target, **self.colors))
                sys.stdout.flush()

            if not expected_connections:
                return

            time.sleep(1)
            now = datetime.now()
        else:
            print('\n {RED_BOLD}*{ENDC} WARNING: Minions failed to connect '
                  'back. Tests requiring them WILL fail'.format(**self.colors))
            print_header('=', sep='=', inline=True)
            raise SystemExit()
Exemple #4
0
    def __enter__(self):
        '''
        Start a master and minion
        '''
        running_tests_user = pwd.getpwuid(os.getuid()).pw_name
        self.master_opts = salt.config.master_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master'))
        self.master_opts['user'] = running_tests_user
        minion_config_path = os.path.join(INTEGRATION_TEST_DIR, 'files',
                                          'conf', 'minion')
        self.minion_opts = salt.config.minion_config(minion_config_path)
        self.minion_opts['user'] = running_tests_user
        self.syndic_opts = salt.config.syndic_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'syndic'),
            minion_config_path)
        self.syndic_opts['user'] = running_tests_user

        #if sys.version_info < (2, 7):
        #    self.minion_opts['multiprocessing'] = False
        self.sub_minion_opts = salt.config.minion_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'sub_minion'))
        self.sub_minion_opts['root_dir'] = os.path.join(TMP, 'subsalt')
        self.sub_minion_opts['user'] = running_tests_user
        #if sys.version_info < (2, 7):
        #    self.sub_minion_opts['multiprocessing'] = False
        self.smaster_opts = salt.config.master_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf',
                         'syndic_master'))
        self.smaster_opts['user'] = running_tests_user

        # Set up config options that require internal data
        self.master_opts['pillar_roots'] = {
            'base': [os.path.join(FILES, 'pillar', 'base')]
        }
        self.master_opts['file_roots'] = {
            'base': [
                os.path.join(FILES, 'file', 'base'),
                # Let's support runtime created files that can be used like:
                #   salt://my-temp-file.txt
                TMP_STATE_TREE
            ],
            # Alternate root to test __env__ choices
            'prod':
            [os.path.join(FILES, 'file', 'prod'), TMP_PRODENV_STATE_TREE]
        }
        self.master_opts['ext_pillar'].append(
            {'cmd_yaml': 'cat {0}'.format(os.path.join(FILES, 'ext.yaml'))})

        self.master_opts['extension_modules'] = os.path.join(
            INTEGRATION_TEST_DIR, 'files', 'extension_modules')

        # clean up the old files
        self._clean()

        # Point the config values to the correct temporary paths
        for name in ('hosts', 'aliases'):
            optname = '{0}.file'.format(name)
            optname_path = os.path.join(TMP, name)
            self.master_opts[optname] = optname_path
            self.minion_opts[optname] = optname_path
            self.sub_minion_opts[optname] = optname_path

        verify_env([
            os.path.join(self.master_opts['pki_dir'], 'minions'),
            os.path.join(self.master_opts['pki_dir'], 'minions_pre'),
            os.path.join(self.master_opts['pki_dir'], 'minions_rejected'),
            os.path.join(self.master_opts['cachedir'], 'jobs'),
            os.path.join(self.smaster_opts['pki_dir'], 'minions'),
            os.path.join(self.smaster_opts['pki_dir'], 'minions_pre'),
            os.path.join(self.smaster_opts['pki_dir'], 'minions_rejected'),
            os.path.join(self.smaster_opts['cachedir'], 'jobs'),
            os.path.dirname(self.master_opts['log_file']),
            self.minion_opts['extension_modules'],
            self.sub_minion_opts['extension_modules'],
            self.sub_minion_opts['pki_dir'],
            self.master_opts['sock_dir'],
            self.smaster_opts['sock_dir'],
            self.sub_minion_opts['sock_dir'],
            self.minion_opts['sock_dir'],
            TMP_STATE_TREE,
            TMP_PRODENV_STATE_TREE,
            TMP,
        ], running_tests_user)

        # Set up PATH to mockbin
        self._enter_mockbin()

        master = salt.master.Master(self.master_opts)
        self.master_process = multiprocessing.Process(target=master.start)
        self.master_process.start()

        minion = salt.minion.Minion(self.minion_opts)
        self.minion_process = multiprocessing.Process(target=minion.tune_in)
        self.minion_process.start()

        sub_minion = salt.minion.Minion(self.sub_minion_opts)
        self.sub_minion_process = multiprocessing.Process(
            target=sub_minion.tune_in)
        self.sub_minion_process.start()

        smaster = salt.master.Master(self.smaster_opts)
        self.smaster_process = multiprocessing.Process(target=smaster.start)
        self.smaster_process.start()

        syndic = salt.minion.Syndic(self.syndic_opts)
        self.syndic_process = multiprocessing.Process(target=syndic.tune_in)
        self.syndic_process.start()

        if os.environ.get('DUMP_SALT_CONFIG', None) is not None:
            from copy import deepcopy
            try:
                os.makedirs('/tmp/salttest/conf')
            except OSError:
                pass
            master_opts = deepcopy(self.master_opts)
            minion_opts = deepcopy(self.minion_opts)
            master_opts.pop('conf_file', None)

            minion_opts.pop('conf_file', None)
            minion_opts.pop('grains', None)
            minion_opts.pop('pillar', None)
            open('/tmp/salttest/conf/master',
                 'w').write(yaml.dump(master_opts))
            open('/tmp/salttest/conf/minion',
                 'w').write(yaml.dump(minion_opts))

        self.minion_targets = set(['minion', 'sub_minion'])
        self.pre_setup_minions()
        self.setup_minions()

        if self.parser.options.ssh:
            self.prep_ssh()

        if self.parser.options.sysinfo:
            try:
                print_header('~~~~~~~ Versions Report ',
                             inline=True,
                             width=getattr(self.parser.options,
                                           'output_columns', PNUM))
            except TypeError:
                print_header('~~~~~~~ Versions Report ', inline=True)

            print('\n'.join(salt.version.versions_report()))

            try:
                print_header('~~~~~~~ Minion Grains Information ',
                             inline=True,
                             width=getattr(self.parser.options,
                                           'output_columns', PNUM))
            except TypeError:
                print_header('~~~~~~~ Minion Grains Information ', inline=True)

            grains = self.client.cmd('minion', 'grains.items')

            minion_opts = self.minion_opts.copy()
            minion_opts['color'] = self.parser.options.no_colors is False
            salt.output.display_output(grains, 'grains', minion_opts)

        try:
            print_header('=',
                         sep='=',
                         inline=True,
                         width=getattr(self.parser.options, 'output_columns',
                                       PNUM))
        except TypeError:
            print_header('', sep='=', inline=True)

        try:
            return self
        finally:
            self.post_setup_minions()
Exemple #5
0
    def run_integration_tests(self):
        '''
        Execute the integration tests suite
        '''
        named_tests = []
        named_unit_test = []

        if self.options.name:
            for test in self.options.name:
                if test.startswith('unit.'):
                    named_unit_test.append(test)
                    continue
                named_tests.append(test)

        if (self.options.unit or named_unit_test) and not \
                (self.options.runners or
                 self.options.state or
                 self.options.module or
                 self.options.cli or
                 self.options.client or
                 self.options.loader or
                 self.options.outputter or
                 self.options.fileserver or
                 self.options.wheel or
                 self.options.cloud_provider_tests or
                 named_tests):
            # We're either not running any of runners, state, module and client
            # tests, or, we're only running unittests by passing --unit or by
            # passing only `unit.<whatever>` to --name.
            # We don't need the tests daemon running
            return [True]
        self.prep_filehandles()

        try:
            print_header(' * Setting up Salt daemons to execute tests',
                         top=False,
                         width=getattr(self.options, 'output_columns', PNUM))
        except TypeError:
            print_header(' * Setting up Salt daemons to execute tests',
                         top=False)

        status = []
        if not any([
                self.options.cli, self.options.client, self.options.module,
                self.options.runners, self.options.shell, self.options.state,
                self.options.loader, self.options.outputter, self.options.name,
                self.options.cloud_provider_tests, self.options.api,
                self.options.fileserver, self.options.wheel
        ]):
            return status

        with TestDaemon(self):
            if self.options.name:
                for name in self.options.name:
                    if name.startswith('unit.'):
                        continue
                    results = self.run_suite('', name, load_from_name=True)
                    status.append(results)
            if self.options.loader:
                status.append(self.run_integration_suite('loader', 'Loader'))
            if self.options.runners:
                status.append(self.run_integration_suite('runners', 'Runners'))
            if self.options.module:
                status.append(self.run_integration_suite('modules', 'Module'))
            if self.options.state:
                status.append(self.run_integration_suite('states', 'State'))
            if self.options.cli:
                status.append(self.run_integration_suite('cli', 'CLI'))
            if self.options.client:
                status.append(self.run_integration_suite('client', 'Client'))
            if self.options.shell:
                status.append(self.run_integration_suite('shell', 'Shell'))
            if self.options.outputter:
                status.append(self.run_integration_suite(
                    'output', 'Outputter'))
            if self.options.fileserver:
                status.append(
                    self.run_integration_suite('fileserver', 'Fileserver'))
            if self.options.wheel:
                status.append(self.run_integration_suite('wheel', 'Wheel'))
            if self.options.cloud_provider_tests:
                status.append(
                    self.run_integration_suite('cloud/providers',
                                               'Cloud Provider'))
            if self.options.api:
                status.append(self.run_integration_suite('netapi', 'NetAPI'))
        return status
Exemple #6
0
    def start_daemons_only(self):
        self.prep_filehandles()
        try:
            print_header(' * Setting up Salt daemons for interactive use',
                         top=False,
                         width=getattr(self.options, 'output_columns', PNUM))
        except TypeError:
            print_header(' * Setting up Salt daemons for interactive use',
                         top=False)

        with TestDaemon(self):
            print_header(' * Salt daemons started')
            master_conf = TestDaemon.config('master')
            minion_conf = TestDaemon.config('minion')
            syndic_conf = TestDaemon.config('syndic')
            syndic_master_conf = TestDaemon.config('syndic_master')

            print_header(' * Syndic master configuration values', top=False)
            print('interface: {0}'.format(syndic_master_conf['interface']))
            print('publish port: {0}'.format(
                syndic_master_conf['publish_port']))
            print('return port: {0}'.format(syndic_master_conf['ret_port']))
            print('\n')

            print_header(' * Master configuration values', top=True)
            print('interface: {0}'.format(master_conf['interface']))
            print('publish port: {0}'.format(master_conf['publish_port']))
            print('return port: {0}'.format(master_conf['ret_port']))
            print('\n')

            print_header(' * Minion configuration values', top=True)
            print('interface: {0}'.format(minion_conf['interface']))
            print('\n')

            print_header(' * Syndic configuration values', top=True)
            print('interface: {0}'.format(syndic_conf['interface']))
            print('syndic master port: {0}'.format(
                syndic_conf['syndic_master']))
            print('\n')

            print_header(' Your client configuration is at {0}'.format(
                TestDaemon.config_location()))
            print('To access the minion: `salt -c {0} minion test.ping'.format(
                TestDaemon.config_location()))

            while True:
                time.sleep(1)
Exemple #7
0
    def start_daemons_only(self):
        if not salt.utils.is_windows():
            self.set_filehandle_limits('integration')
        try:
            print_header(' * Setting up Salt daemons for interactive use',
                         top=False,
                         width=getattr(self.options, 'output_columns', PNUM))
        except TypeError:
            print_header(' * Setting up Salt daemons for interactive use',
                         top=False)

        with TestDaemon(self):
            print_header(' * Salt daemons started')
            master_conf = TestDaemon.config('master')
            minion_conf = TestDaemon.config('minion')
            sub_minion_conf = TestDaemon.config('sub_minion')
            syndic_conf = TestDaemon.config('syndic')
            syndic_master_conf = TestDaemon.config('syndic_master')

            print_header(' * Syndic master configuration values (MoM)',
                         top=False)
            print('interface: {0}'.format(syndic_master_conf['interface']))
            print('publish port: {0}'.format(
                syndic_master_conf['publish_port']))
            print('return port: {0}'.format(syndic_master_conf['ret_port']))
            print('\n')

            print_header(' * Syndic configuration values', top=True)
            print('interface: {0}'.format(syndic_conf['interface']))
            print('syndic master: {0}'.format(syndic_conf['syndic_master']))
            print('syndic master port: {0}'.format(
                syndic_conf['syndic_master_port']))
            print('\n')

            print_header(' * Master configuration values', top=True)
            print('interface: {0}'.format(master_conf['interface']))
            print('publish port: {0}'.format(master_conf['publish_port']))
            print('return port: {0}'.format(master_conf['ret_port']))
            print('\n')

            print_header(' * Minion configuration values', top=True)
            print('interface: {0}'.format(minion_conf['interface']))
            print('master: {0}'.format(minion_conf['master']))
            print('master port: {0}'.format(minion_conf['master_port']))
            if minion_conf['ipc_mode'] == 'tcp':
                print('tcp pub port: {0}'.format(minion_conf['tcp_pub_port']))
                print('tcp pull port: {0}'.format(
                    minion_conf['tcp_pull_port']))
            print('\n')

            print_header(' * Sub Minion configuration values', top=True)
            print('interface: {0}'.format(sub_minion_conf['interface']))
            print('master: {0}'.format(sub_minion_conf['master']))
            print('master port: {0}'.format(sub_minion_conf['master_port']))
            if sub_minion_conf['ipc_mode'] == 'tcp':
                print('tcp pub port: {0}'.format(
                    sub_minion_conf['tcp_pub_port']))
                print('tcp pull port: {0}'.format(
                    sub_minion_conf['tcp_pull_port']))
            print('\n')

            print_header(' Your client configuration is at {0}'.format(
                TestDaemon.config_location()))
            print('To access the minion: salt -c {0} minion test.ping'.format(
                TestDaemon.config_location()))

            while True:
                time.sleep(1)
Exemple #8
0
    def run_integration_tests(self):
        '''
        Execute the integration tests suite
        '''
        named_tests = []
        named_unit_test = []

        if self.options.name:
            for test in self.options.name:
                if test.startswith('unit.'):
                    named_unit_test.append(test)
                    continue
                named_tests.append(test)

        if (self.options.unit or named_unit_test) and not \
                (self.options.runner or
                 self.options.state or
                 self.options.module or
                 self.options.client or
                 named_tests):
            # We're either not running any of runner, state, module and client
            # tests, or, we're only running unittests by passing --unit or by
            # passing only `unit.<whatever>` to --name.
            # We don't need the tests daemon running
            return [True]

        smax_open_files, hmax_open_files = resource.getrlimit(
            resource.RLIMIT_NOFILE
        )
        if smax_open_files < REQUIRED_OPEN_FILES:
            print('~' * PNUM)
            print(
                'Max open files setting is too low({0}) for running the '
                'tests'.format(smax_open_files)
            )
            print(
                'Trying to raise the limit to {0}'.format(REQUIRED_OPEN_FILES)
            )
            if hmax_open_files < 4096:
                hmax_open_files = 4096  # Decent default?
            try:
                resource.setrlimit(
                    resource.RLIMIT_NOFILE,
                    (REQUIRED_OPEN_FILES, hmax_open_files)
                )
            except Exception as err:
                print(
                    'ERROR: Failed to raise the max open files setting -> '
                    '{0}'.format(err)
                )
                print('Please issue the following command on your console:')
                print('  ulimit -n {0}'.format(REQUIRED_OPEN_FILES))
                self.exit()
            finally:
                print('~' * PNUM)

        print_header('Setting up Salt daemons to execute tests', top=False)
        status = []
        if not any([self.options.client, self.options.module,
                    self.options.runner, self.options.shell,
                    self.options.state, self.options.name]):
            return status

        with TestDaemon(self):
            if self.options.name:
                for name in self.options.name:
                    if name.startswith('unit.'):
                        continue
                    results = self.run_suite('', name, load_from_name=True)
                    status.append(results)
            if self.options.runner:
                status.append(self.run_integration_suite('runners', 'Runner'))
            if self.options.module:
                status.append(self.run_integration_suite('modules', 'Module'))
            if self.options.state:
                status.append(self.run_integration_suite('states', 'State'))
            if self.options.client:
                status.append(self.run_integration_suite('client', 'Client'))
            if self.options.shell:
                status.append(self.run_integration_suite('shell', 'Shell'))
        return status
Exemple #9
0
    def run_integration_tests(self):
        '''
        Execute the integration tests suite
        '''
        named_tests = []
        named_unit_test = []

        if self.options.name:
            for test in self.options.name:
                if test.startswith('unit.'):
                    named_unit_test.append(test)
                    continue
                named_tests.append(test)

        if (self.options.unit or named_unit_test) and not \
                (self.options.runners or
                 self.options.state or
                 self.options.module or
                 self.options.cli or
                 self.options.client or
                 self.options.loader or
                 self.options.outputter or
                 self.options.fileserver or
                 self.options.wheel or
                 self.options.cloud_provider_tests or
                 self.options.api or
                 named_tests):
            # We're either not running any of runners, state, module and client
            # tests, or, we're only running unittests by passing --unit or by
            # passing only `unit.<whatever>` to --name.
            # We don't need the tests daemon running
            return [True]
        self.prep_filehandles()

        try:
            print_header(
                ' * Setting up Salt daemons to execute tests',
                top=False, width=getattr(self.options, 'output_columns', PNUM)
            )
        except TypeError:
            print_header(' * Setting up Salt daemons to execute tests', top=False)

        status = []
        if not any([self.options.cli, self.options.client, self.options.module,
                    self.options.runners, self.options.shell, self.options.state,
                    self.options.loader, self.options.outputter, self.options.name,
                    self.options.cloud_provider_tests, self.options.api,
                    self.options.fileserver, self.options.wheel]):
            return status

        with TestDaemon(self):
            if self.options.name:
                for name in self.options.name:
                    if name.startswith('unit.'):
                        continue
                    results = self.run_suite('', name, load_from_name=True)
                    status.append(results)
            if self.options.loader:
                status.append(self.run_integration_suite('loader', 'Loader'))
            if self.options.runners:
                status.append(self.run_integration_suite('runners', 'Runners'))
            if self.options.module:
                status.append(self.run_integration_suite('modules', 'Module'))
            if self.options.state:
                status.append(self.run_integration_suite('states', 'State'))
            if self.options.cli:
                status.append(self.run_integration_suite('cli', 'CLI'))
            if self.options.client:
                status.append(self.run_integration_suite('client', 'Client'))
            if self.options.shell:
                status.append(self.run_integration_suite('shell', 'Shell'))
            if self.options.outputter:
                status.append(self.run_integration_suite('output', 'Outputter'))
            if self.options.fileserver:
                status.append(self.run_integration_suite('fileserver', 'Fileserver'))
            if self.options.wheel:
                status.append(self.run_integration_suite('wheel', 'Wheel'))
            if self.options.cloud_provider_tests:
                status.append(self.run_integration_suite('cloud/providers', 'Cloud Provider'))
            if self.options.api:
                status.append(self.run_integration_suite('netapi', 'NetAPI'))
        return status
Exemple #10
0
    def start_daemons_only(self):
        self.prep_filehandles()
        try:
            print_header(
                ' * Setting up Salt daemons for interactive use',
                top=False, width=getattr(self.options, 'output_columns', PNUM)
            )
        except TypeError:
            print_header(' * Setting up Salt daemons for interactive use', top=False)

        with TestDaemon(self):
            print_header(' * Salt daemons started')
            master_conf = TestDaemon.config('master')
            minion_conf = TestDaemon.config('minion')
            syndic_conf = TestDaemon.config('syndic')
            syndic_master_conf = TestDaemon.config('syndic_master')

            print_header(' * Syndic master configuration values', top=False)
            print('interface: {0}'.format(syndic_master_conf['interface']))
            print('publish port: {0}'.format(syndic_master_conf['publish_port']))
            print('return port: {0}'.format(syndic_master_conf['ret_port']))
            print('\n')

            print_header(' * Master configuration values', top=True)
            print('interface: {0}'.format(master_conf['interface']))
            print('publish port: {0}'.format(master_conf['publish_port']))
            print('return port: {0}'.format(master_conf['ret_port']))
            print('\n')

            print_header(' * Minion configuration values', top=True)
            print('interface: {0}'.format(minion_conf['interface']))
            print('\n')

            print_header(' * Syndic configuration values', top=True)
            print('interface: {0}'.format(syndic_conf['interface']))
            print('syndic master port: {0}'.format(syndic_conf['syndic_master']))
            print('\n')

            print_header(' Your client configuration is at {0}'.format(TestDaemon.config_location()))
            print('To access the minion: `salt -c {0} minion test.ping'.format(TestDaemon.config_location()))

            while True:
                time.sleep(1)
Exemple #11
0
    def run_integration_tests(self):
        '''
        Execute the integration tests suite
        '''
        named_tests = []
        named_unit_test = []

        if self.options.name:
            for test in self.options.name:
                if test.startswith('unit.'):
                    named_unit_test.append(test)
                    continue
                named_tests.append(test)

        if (self.options.unit or named_unit_test) and not \
                (self.options.runners or
                 self.options.state or
                 self.options.module or
                 self.options.cli or
                 self.options.client or
                 self.options.loader or
                 self.options.outputter or
                 self.options.fileserver or
                 self.options.wheel or
                 self.options.cloud_provider_tests or
                 named_tests):
            # We're either not running any of runners, state, module and client
            # tests, or, we're only running unittests by passing --unit or by
            # passing only `unit.<whatever>` to --name.
            # We don't need the tests daemon running
            return [True]

        smax_open_files, hmax_open_files = resource.getrlimit(
            resource.RLIMIT_NOFILE)
        if smax_open_files < REQUIRED_OPEN_FILES:
            print(' * Max open files setting is too low({0}) for running the '
                  'tests'.format(smax_open_files))
            print(' * Trying to raise the limit to {0}'.format(
                REQUIRED_OPEN_FILES))
            if hmax_open_files < 4096:
                hmax_open_files = 4096  # Decent default?
            try:
                resource.setrlimit(resource.RLIMIT_NOFILE,
                                   (REQUIRED_OPEN_FILES, hmax_open_files))
            except Exception as err:
                print('ERROR: Failed to raise the max open files setting -> '
                      '{0}'.format(err))
                print('Please issue the following command on your console:')
                print('  ulimit -n {0}'.format(REQUIRED_OPEN_FILES))
                self.exit()
            finally:
                print('~' * getattr(self.options, 'output_columns', PNUM))

        try:
            print_header(' * Setting up Salt daemons to execute tests',
                         top=False,
                         width=getattr(self.options, 'output_columns', PNUM))
        except TypeError:
            print_header(' * Setting up Salt daemons to execute tests',
                         top=False)

        status = []
        if not any([
                self.options.cli, self.options.client, self.options.module,
                self.options.runners, self.options.shell, self.options.state,
                self.options.loader, self.options.outputter, self.options.name,
                self.options.cloud_provider_tests, self.options.api,
                self.options.fileserver, self.options.wheel
        ]):
            return status

        with TestDaemon(self):
            if self.options.name:
                for name in self.options.name:
                    if name.startswith('unit.'):
                        continue
                    results = self.run_suite('', name, load_from_name=True)
                    status.append(results)
            if self.options.loader:
                status.append(self.run_integration_suite('loader', 'Loader'))
            if self.options.runners:
                status.append(self.run_integration_suite('runners', 'Runners'))
            if self.options.module:
                status.append(self.run_integration_suite('modules', 'Module'))
            if self.options.state:
                status.append(self.run_integration_suite('states', 'State'))
            if self.options.cli:
                status.append(self.run_integration_suite('cli', 'CLI'))
            if self.options.client:
                status.append(self.run_integration_suite('client', 'Client'))
            if self.options.shell:
                status.append(self.run_integration_suite('shell', 'Shell'))
            if self.options.outputter:
                status.append(self.run_integration_suite(
                    'output', 'Outputter'))
            if self.options.fileserver:
                status.append(
                    self.run_integration_suite('fileserver', 'Fileserver'))
            if self.options.wheel:
                status.append(self.run_integration_suite('wheel', 'Wheel'))
            if self.options.cloud_provider_tests:
                status.append(
                    self.run_integration_suite('cloud/providers',
                                               'Cloud Provider'))
            if self.options.api:
                status.append(self.run_integration_suite('netapi', 'NetAPI'))
        return status
Exemple #12
0
    def __enter__(self):
        '''
        Start a master and minion
        '''
        running_tests_user = pwd.getpwuid(os.getuid()).pw_name
        self.master_opts = salt.config.master_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'master')
        )
        self.master_opts['user'] = running_tests_user
        minion_config_path = os.path.join(
            INTEGRATION_TEST_DIR, 'files', 'conf', 'minion'
        )
        self.minion_opts = salt.config.minion_config(minion_config_path)
        self.minion_opts['user'] = running_tests_user
        self.syndic_opts = salt.config.syndic_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'syndic'),
            minion_config_path
        )
        self.syndic_opts['user'] = running_tests_user

        #if sys.version_info < (2, 7):
        #    self.minion_opts['multiprocessing'] = False
        self.sub_minion_opts = salt.config.minion_config(
            os.path.join(INTEGRATION_TEST_DIR, 'files', 'conf', 'sub_minion')
        )
        self.sub_minion_opts['root_dir'] = os.path.join(TMP, 'subsalt')
        self.sub_minion_opts['user'] = running_tests_user
        #if sys.version_info < (2, 7):
        #    self.sub_minion_opts['multiprocessing'] = False
        self.smaster_opts = salt.config.master_config(
            os.path.join(
                INTEGRATION_TEST_DIR, 'files', 'conf', 'syndic_master'
            )
        )
        self.smaster_opts['user'] = running_tests_user

        # Set up config options that require internal data
        self.master_opts['pillar_roots'] = {
            'base': [os.path.join(FILES, 'pillar', 'base')]
        }
        self.master_opts['file_roots'] = {
            'base': [
                os.path.join(FILES, 'file', 'base'),
                # Let's support runtime created files that can be used like:
                #   salt://my-temp-file.txt
                TMP_STATE_TREE
            ],
            # Alternate root to test __env__ choices
            'prod': [
                os.path.join(FILES, 'file', 'prod'),
                TMP_PRODENV_STATE_TREE
            ]
        }
        self.master_opts['ext_pillar'].append(
            {'cmd_yaml': 'cat {0}'.format(
                os.path.join(
                    FILES,
                    'ext.yaml'
                )
            )}
        )

        self.master_opts['extension_modules'] = os.path.join(
            INTEGRATION_TEST_DIR, 'files', 'extension_modules'
        )

        # clean up the old files
        self._clean()

        # Point the config values to the correct temporary paths
        for name in ('hosts', 'aliases'):
            optname = '{0}.file'.format(name)
            optname_path = os.path.join(TMP, name)
            self.master_opts[optname] = optname_path
            self.minion_opts[optname] = optname_path
            self.sub_minion_opts[optname] = optname_path

        verify_env([os.path.join(self.master_opts['pki_dir'], 'minions'),
                    os.path.join(self.master_opts['pki_dir'], 'minions_pre'),
                    os.path.join(self.master_opts['pki_dir'],
                                 'minions_rejected'),
                    os.path.join(self.master_opts['cachedir'], 'jobs'),
                    os.path.join(self.smaster_opts['pki_dir'], 'minions'),
                    os.path.join(self.smaster_opts['pki_dir'], 'minions_pre'),
                    os.path.join(self.smaster_opts['pki_dir'],
                                 'minions_rejected'),
                    os.path.join(self.smaster_opts['cachedir'], 'jobs'),
                    os.path.dirname(self.master_opts['log_file']),
                    self.minion_opts['extension_modules'],
                    self.sub_minion_opts['extension_modules'],
                    self.sub_minion_opts['pki_dir'],
                    self.master_opts['sock_dir'],
                    self.smaster_opts['sock_dir'],
                    self.sub_minion_opts['sock_dir'],
                    self.minion_opts['sock_dir'],
                    TMP_STATE_TREE,
                    TMP_PRODENV_STATE_TREE,
                    TMP,
                    ],
                   running_tests_user)

        # Set up PATH to mockbin
        self._enter_mockbin()

        master = salt.master.Master(self.master_opts)
        self.master_process = multiprocessing.Process(target=master.start)
        self.master_process.start()

        minion = salt.minion.Minion(self.minion_opts)
        self.minion_process = multiprocessing.Process(target=minion.tune_in)
        self.minion_process.start()

        sub_minion = salt.minion.Minion(self.sub_minion_opts)
        self.sub_minion_process = multiprocessing.Process(
            target=sub_minion.tune_in
        )
        self.sub_minion_process.start()

        smaster = salt.master.Master(self.smaster_opts)
        self.smaster_process = multiprocessing.Process(target=smaster.start)
        self.smaster_process.start()

        syndic = salt.minion.Syndic(self.syndic_opts)
        self.syndic_process = multiprocessing.Process(target=syndic.tune_in)
        self.syndic_process.start()

        if os.environ.get('DUMP_SALT_CONFIG', None) is not None:
            from copy import deepcopy
            try:
                os.makedirs('/tmp/salttest/conf')
            except OSError:
                pass
            master_opts = deepcopy(self.master_opts)
            minion_opts = deepcopy(self.minion_opts)
            master_opts.pop('conf_file', None)

            minion_opts.pop('conf_file', None)
            minion_opts.pop('grains', None)
            minion_opts.pop('pillar', None)
            open('/tmp/salttest/conf/master', 'w').write(
                yaml.dump(master_opts)
            )
            open('/tmp/salttest/conf/minion', 'w').write(
                yaml.dump(minion_opts)
            )

        self.minion_targets = set(['minion', 'sub_minion'])
        self.pre_setup_minions()
        self.setup_minions()

        if self.parser.options.sysinfo:
            try:
                print_header(
                    '~~~~~~~ Versions Report ', inline=True,
                    width=getattr(self.parser.options, 'output_columns', PNUM)
                )
            except TypeError:
                print_header('~~~~~~~ Versions Report ', inline=True)

            print('\n'.join(salt.version.versions_report()))

            try:
                print_header(
                    '~~~~~~~ Minion Grains Information ', inline=True,
                    width=getattr(self.parser.options, 'output_columns', PNUM)
                )
            except TypeError:
                print_header('~~~~~~~ Minion Grains Information ', inline=True)

            grains = self.client.cmd('minion', 'grains.items')

            minion_opts = self.minion_opts.copy()
            minion_opts['color'] = self.parser.options.no_colors is False
            salt.output.display_output(grains, 'grains', minion_opts)

        try:
            print_header(
                '=', sep='=', inline=True,
                width=getattr(self.parser.options, 'output_columns', PNUM)
            )
        except TypeError:
            print_header('', sep='=', inline=True)

        try:
            return self
        finally:
            self.post_setup_minions()