blob: a4ed064d50beb65982142676a0f76c3b6e81815a [file] [log] [blame]
Matthew Treinishf610aca2015-06-30 15:32:34 -04001# Copyright 2015 Hewlett-Packard Development Company, L.P.
2#
3# Licensed under the Apache License, Version 2.0 (the "License"); you may
4# not use this file except in compliance with the License. You may obtain
5# a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12# License for the specific language governing permissions and limitations
13# under the License.
14
15import os
16import shutil
17import subprocess
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010018import sys
Matthew Treinishf610aca2015-06-30 15:32:34 -040019
20from cliff import command
21from oslo_log import log as logging
22from six import moves
23
24LOG = logging.getLogger(__name__)
25
26TESTR_CONF = """[DEFAULT]
27test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \\
28 OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \\
29 OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-500} \\
30 ${PYTHON:-python} -m subunit.run discover -t %s %s $LISTOPT $IDOPTION
31test_id_option=--load-list $IDFILE
32test_list_option=--list
33group_regex=([^\.]*\.)*
34"""
35
36
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010037def get_tempest_default_config_dir():
38 """Returns the correct default config dir to support both cases of
39 tempest being or not installed in a virtualenv.
40 Cases considered:
41 - no virtual env, python2: real_prefix and base_prefix not set
42 - no virtual env, python3: real_prefix not set, base_prefix set and
43 identical to prefix
44 - virtualenv, python2: real_prefix and prefix are set and different
45 - virtualenv, python3: real_prefix not set, base_prefix and prefix are
46 set and identical
47 - pyvenv, any python version: real_prefix not set, base_prefix and prefix
48 are set and different
49
50 :return: default config dir
51 """
52 real_prefix = getattr(sys, 'real_prefix', None)
53 base_prefix = getattr(sys, 'base_prefix', None)
54 prefix = sys.prefix
David Paterson0bf52d42015-04-13 21:55:58 -040055 if (real_prefix is None and
56 (base_prefix is None or base_prefix == prefix)):
57 # Probably not running in a virtual environment.
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010058 # NOTE(andreaf) we cannot distinguish this case from the case of
59 # a virtual environment created with virtualenv, and running python3.
David Paterson0bf52d42015-04-13 21:55:58 -040060 # Also if it appears we are not in virtual env and fail to find
61 # global config: '/etc/tempest', fall back to
62 # '[sys.prefix]/etc/tempest'
63 global_conf_dir = '/etc/tempest'
64 if os.path.isdir(global_conf_dir):
65 return global_conf_dir
66 else:
67 return os.path.join(prefix, 'etc/tempest')
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010068 else:
David Paterson0bf52d42015-04-13 21:55:58 -040069 return os.path.join(prefix, 'etc/tempest')
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010070
71
Matthew Treinishf610aca2015-06-30 15:32:34 -040072class TempestInit(command.Command):
73 """Setup a local working environment for running tempest"""
74
75 def get_parser(self, prog_name):
76 parser = super(TempestInit, self).get_parser(prog_name)
77 parser.add_argument('dir', nargs='?', default=os.getcwd())
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +010078 parser.add_argument('--config-dir', '-c', default=None)
Matthew Treinishf610aca2015-06-30 15:32:34 -040079 return parser
80
81 def generate_testr_conf(self, local_path):
82 testr_conf_path = os.path.join(local_path, '.testr.conf')
83 top_level_path = os.path.dirname(os.path.dirname(__file__))
84 discover_path = os.path.join(top_level_path, 'test_discover')
85 testr_conf = TESTR_CONF % (top_level_path, discover_path)
86 with open(testr_conf_path, 'w+') as testr_conf_file:
87 testr_conf_file.write(testr_conf)
88
89 def update_local_conf(self, conf_path, lock_dir, log_dir):
90 config_parse = moves.configparser.SafeConfigParser()
91 config_parse.optionxform = str
92 with open(conf_path, 'w+') as conf_file:
93 config_parse.readfp(conf_file)
94 # Set local lock_dir in tempest conf
95 if not config_parse.has_section('oslo_concurrency'):
96 config_parse.add_section('oslo_concurrency')
97 config_parse.set('oslo_concurrency', 'lock_path', lock_dir)
98 # Set local log_dir in tempest conf
99 config_parse.set('DEFAULT', 'log_dir', log_dir)
100 # Set default log filename to tempest.log
101 config_parse.set('DEFAULT', 'log_file', 'tempest.log')
102
103 def copy_config(self, etc_dir, config_dir):
104 shutil.copytree(config_dir, etc_dir)
105
David Paterson0bf52d42015-04-13 21:55:58 -0400106 def generate_sample_config(self, local_dir, config_dir):
107 conf_generator = os.path.join(config_dir,
108 'config-generator.tempest.conf')
109
Matthew Treinishc8a39b42015-07-27 17:07:37 -0400110 subprocess.call(['oslo-config-generator', '--config-file',
David Paterson0bf52d42015-04-13 21:55:58 -0400111 conf_generator],
Matthew Treinishc8a39b42015-07-27 17:07:37 -0400112 cwd=local_dir)
113
Matthew Treinishf610aca2015-06-30 15:32:34 -0400114 def create_working_dir(self, local_dir, config_dir):
115 # Create local dir if missing
116 if not os.path.isdir(local_dir):
117 LOG.debug('Creating local working dir: %s' % local_dir)
118 os.mkdir(local_dir)
Marc Koderer090b5dc2015-11-04 10:35:48 +0100119 elif not os.listdir(local_dir) == []:
David Paterson0bf52d42015-04-13 21:55:58 -0400120 raise OSError("Directory you are trying to initialize already "
Marc Koderer090b5dc2015-11-04 10:35:48 +0100121 "exists and is not empty: %s" % local_dir)
David Paterson0bf52d42015-04-13 21:55:58 -0400122
Matthew Treinishf610aca2015-06-30 15:32:34 -0400123 lock_dir = os.path.join(local_dir, 'tempest_lock')
124 etc_dir = os.path.join(local_dir, 'etc')
125 config_path = os.path.join(etc_dir, 'tempest.conf')
126 log_dir = os.path.join(local_dir, 'logs')
127 testr_dir = os.path.join(local_dir, '.testrepository')
128 # Create lock dir
129 if not os.path.isdir(lock_dir):
130 LOG.debug('Creating lock dir: %s' % lock_dir)
131 os.mkdir(lock_dir)
132 # Create log dir
133 if not os.path.isdir(log_dir):
134 LOG.debug('Creating log dir: %s' % log_dir)
135 os.mkdir(log_dir)
136 # Create and copy local etc dir
137 self.copy_config(etc_dir, config_dir)
Matthew Treinishc8a39b42015-07-27 17:07:37 -0400138 # Generate the sample config file
David Paterson0bf52d42015-04-13 21:55:58 -0400139 self.generate_sample_config(local_dir, config_dir)
Matthew Treinishf610aca2015-06-30 15:32:34 -0400140 # Update local confs to reflect local paths
141 self.update_local_conf(config_path, lock_dir, log_dir)
142 # Generate a testr conf file
143 self.generate_testr_conf(local_dir)
144 # setup local testr working dir
145 if not os.path.isdir(testr_dir):
146 subprocess.call(['testr', 'init'], cwd=local_dir)
147
148 def take_action(self, parsed_args):
Andrea Frittoli (andreaf)5a69e552015-07-31 18:40:17 +0100149 config_dir = parsed_args.config_dir or get_tempest_default_config_dir()
150 self.create_working_dir(parsed_args.dir, config_dir)