class BaseDumbqTest(unittest.TestCase): """Base test class that initializes and destroys DumbQ environment.""" def setUp(self): """Set up and replicate the production environment before testing.""" self.config = config self.feedback = feedback # Just declare, lazy initialization self.logger = logger self.hardware_info = None self.dumbq_setup = None self.project_hub = None self.project_manager = None self.replicate_production_environment() def replicate_production_environment(self): """Mock the environment with temp files, solving dependencies.""" tempfile.tempdir = tempfile.mkdtemp(dir="/tmp") # Mock cernvm environment _, self.uuid_fp = tempfile.mkstemp() self.config["uuid_file"] = self.uuid_fp _, self.cernvmconf_fp = tempfile.mkstemp() self.config["local_cernvm_config"] = self.cernvmconf_fp # Mock dumbq environment self.dumbq_dir = tempfile.mkdtemp() self.config["dumbq_dir"] = self.dumbq_dir self.www_dir = tempfile.mkdtemp() self.config["www_dir"] = self.www_dir self.setup_config_files() # Bind mount directories _, self.shared = tempfile.mkstemp() _, self.guest = tempfile.mkstemp() self.config["shared_meta_file"] = self.shared + "=" + self.guest # Set up with a few environment variables _, self.envvar_file = tempfile.mkstemp() self.config["envvar_file"] = self.envvar_file self.envvar_floppy = "GREETING", "hello" self.envvar = "FAREWELL", "goodbye" write_to_file("/dev/fd0", "=".join(self.envvar_floppy)) write_to_file(self.envvar_file, "=".join(self.envvar)) # Tty enabled self.config["base_tty"] = 2 def setup_config_files(self): """Define the configuration files to be tested afterwards.""" dirname = os.path.dirname dumbq_folder = dirname(dirname(dirname(os.path.abspath(__file__)))) bootstrap = os.path.join(dumbq_folder, "bootstraps/testing/dummy.sh") self.valid_config_content = "\n".join(( "test1:80:sft.cern.ch:" + bootstrap, "test2:20:sft.cern.ch:" + bootstrap, )) self.invalid_config_content = "\n".join(( "test1:05:sft.cern.ch:../malign/script.sh", "test2::sft.cern.ch:sft.cern.ch/lcg/experimental/bootstrap.sh", "test3:80::", ":80:sft.cern.ch:", ":::", )) self.incomplete_config_content = "\n".join(( "test1:45:sft.cern.ch:sft.cern.ch/lcg/init-bootstrap.sh", "test2:45:sft.cern.ch:sft.cern.ch/lcg/init-bootstrap2.sh", )) self.pref_config_content = "\n".join(( "test1:90", "test2:10", )) self.pref_config_content2 = "\n".join(( "test1:30", "test2:40", "*:50", )) _, self.config_source = tempfile.mkstemp() self.config["config_source"] = self.config_source def init_hw_info(self): """Init logger and hardware info with its dependencies.""" self.hardware_info = HardwareInfo(self.config, self.feedback, self.logger) def init_dumbq_setup(self): """Init dumbq setup with its dependencies.""" self.init_hw_info() self.dumbq_setup = DumbqSetup(self.hardware_info, self.config, self.logger) def init_project_hub(self, config_content=None, pref_content=None): """Init project hub with its dependencies.""" self.init_dumbq_setup() self.dumbq_setup.basic_setup() self.dumbq_setup.setup_dumbq_folders() self.dumbq_setup.setup_logger() self.dumbq_setup.setup_public_www() config_content = config_content or self.valid_config_content pref_content = pref_content or "" self.pref_config_source = config["preference_config_source"] write_to_file(self.config_source, config_content) write_to_file(self.pref_config_source, pref_content) self.run_dir = self.config["dumbq_rundir"] self.project_hub = ProjectHub(self.config, self.feedback, self.logger) def init_project_manager(self): """Init project manager with its dependencies.""" self.init_project_hub() self.project_hub.fetch_config_file() self.project_hub.fetch_preference_file() self.project_hub.parse_shared_and_guest_metadata_file() self.project_manager = ProjectManager(self.project_hub, self.hardware_info, self.config, self.feedback, self.logger) def tearDown(self): """Destroy environment and free used resources.""" self.hardware_info = None self.logger = None self.dumbq_setup = None self.project_hub = None self.project_manager = None self.config = None # Remove tempfiles shutil.rmtree(tempfile.tempdir, ignore_errors=True) ############################################################ # Monkey patch from unittest 2.7 advanced assert functions # ############################################################ def _formatMessage(self, msg, standardMsg): """Honour the longMessage attribute when generating failure messages. If longMessage is False this means: * Use only an explicit message if it is provided * Otherwise use the standard message for the assert If longMessage is True: * Use the standard message * If an explicit message is provided, plus ' : ' and the exp message """ self.longMessage = False if not self.longMessage: return msg or standardMsg if msg is None: return standardMsg try: # don't switch to '{}' formatting in Python 2.X # it changes the way unicode input is handled return '%s : %s' % (standardMsg, msg) except UnicodeDecodeError: return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) def assertIn(self, member, container, msg=None): """Just like self.assertTrue(a in b), with a nicer default message.""" if member not in container: standardMsg = '%s not found in %s' % (safe_repr(member), safe_repr(container)) self.fail(self._formatMessage(msg, standardMsg)) def assertIsInstance(self, obj, cls, msg=None): """Same as self.assertTrue(isinstance(obj, cls)), with a nicer default message.""" if not isinstance(obj, cls): standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) self.fail(self._formatMessage(msg, standardMsg))
class BaseDumbqTest(unittest.TestCase): """Base test class that initializes and destroys DumbQ environment.""" def setUp(self): """Set up and replicate the production environment before testing.""" self.config = config self.feedback = feedback # Just declare, lazy initialization self.logger = logger self.hardware_info = None self.dumbq_setup = None self.project_hub = None self.project_manager = None self.replicate_production_environment() def replicate_production_environment(self): """Mock the environment with temp files, solving dependencies.""" tempfile.tempdir = tempfile.mkdtemp(dir="/tmp") # Mock cernvm environment _, self.uuid_fp = tempfile.mkstemp() self.config["uuid_file"] = self.uuid_fp _, self.cernvmconf_fp = tempfile.mkstemp() self.config["local_cernvm_config"] = self.cernvmconf_fp # Mock dumbq environment self.dumbq_dir = tempfile.mkdtemp() self.config["dumbq_dir"] = self.dumbq_dir self.www_dir = tempfile.mkdtemp() self.config["www_dir"] = self.www_dir self.setup_config_files() # Bind mount directories _, self.shared = tempfile.mkstemp() _, self.guest = tempfile.mkstemp() self.config["shared_meta_file"] = self.shared + "=" + self.guest # Set up with a few environment variables _, self.envvar_file = tempfile.mkstemp() self.config["envvar_file"] = self.envvar_file self.envvar_floppy = "GREETING", "hello" self.envvar = "FAREWELL", "goodbye" write_to_file("/dev/fd0", "=".join(self.envvar_floppy)) write_to_file(self.envvar_file, "=".join(self.envvar)) # Tty enabled self.config["base_tty"] = 2 def setup_config_files(self): """Define the configuration files to be tested afterwards.""" dirname = os.path.dirname dumbq_folder = dirname(dirname(dirname(os.path.abspath(__file__)))) bootstrap = os.path.join(dumbq_folder, "bootstraps/testing/dummy.sh") self.valid_config_content = "\n".join(( "test1:80:sft.cern.ch:" + bootstrap, "test2:20:sft.cern.ch:" + bootstrap, )) self.invalid_config_content = "\n".join(( "test1:05:sft.cern.ch:../malign/script.sh", "test2::sft.cern.ch:sft.cern.ch/lcg/experimental/bootstrap.sh", "test3:80::", ":80:sft.cern.ch:", ":::", )) self.incomplete_config_content = "\n".join(( "test1:45:sft.cern.ch:sft.cern.ch/lcg/init-bootstrap.sh", "test2:45:sft.cern.ch:sft.cern.ch/lcg/init-bootstrap2.sh", )) self.pref_config_content = "\n".join(( "test1:90", "test2:10", )) self.pref_config_content2 = "\n".join(( "test1:30", "test2:40", "*:50", )) _, self.config_source = tempfile.mkstemp() self.config["config_source"] = self.config_source def init_hw_info(self): """Init logger and hardware info with its dependencies.""" self.hardware_info = HardwareInfo( self.config, self.feedback, self.logger ) def init_dumbq_setup(self): """Init dumbq setup with its dependencies.""" self.init_hw_info() self.dumbq_setup = DumbqSetup( self.hardware_info, self.config, self.logger ) def init_project_hub(self, config_content=None, pref_content=None): """Init project hub with its dependencies.""" self.init_dumbq_setup() self.dumbq_setup.basic_setup() self.dumbq_setup.setup_dumbq_folders() self.dumbq_setup.setup_logger() self.dumbq_setup.setup_public_www() config_content = config_content or self.valid_config_content pref_content = pref_content or "" self.pref_config_source = config["preference_config_source"] write_to_file(self.config_source, config_content) write_to_file(self.pref_config_source, pref_content) self.run_dir = self.config["dumbq_rundir"] self.project_hub = ProjectHub( self.config, self.feedback, self.logger ) def init_project_manager(self): """Init project manager with its dependencies.""" self.init_project_hub() self.project_hub.fetch_config_file() self.project_hub.fetch_preference_file() self.project_hub.parse_shared_and_guest_metadata_file() self.project_manager = ProjectManager( self.project_hub, self.hardware_info, self.config, self.feedback, self.logger ) def tearDown(self): """Destroy environment and free used resources.""" self.hardware_info = None self.logger = None self.dumbq_setup = None self.project_hub = None self.project_manager = None self.config = None # Remove tempfiles shutil.rmtree(tempfile.tempdir, ignore_errors=True) ############################################################ # Monkey patch from unittest 2.7 advanced assert functions # ############################################################ def _formatMessage(self, msg, standardMsg): """Honour the longMessage attribute when generating failure messages. If longMessage is False this means: * Use only an explicit message if it is provided * Otherwise use the standard message for the assert If longMessage is True: * Use the standard message * If an explicit message is provided, plus ' : ' and the exp message """ self.longMessage = False if not self.longMessage: return msg or standardMsg if msg is None: return standardMsg try: # don't switch to '{}' formatting in Python 2.X # it changes the way unicode input is handled return '%s : %s' % (standardMsg, msg) except UnicodeDecodeError: return '%s : %s' % (safe_repr(standardMsg), safe_repr(msg)) def assertIn(self, member, container, msg=None): """Just like self.assertTrue(a in b), with a nicer default message.""" if member not in container: standardMsg = '%s not found in %s' % (safe_repr(member), safe_repr(container)) self.fail(self._formatMessage(msg, standardMsg)) def assertIsInstance(self, obj, cls, msg=None): """Same as self.assertTrue(isinstance(obj, cls)), with a nicer default message.""" if not isinstance(obj, cls): standardMsg = '%s is not an instance of %r' % (safe_repr(obj), cls) self.fail(self._formatMessage(msg, standardMsg))
def init_dumbq_setup(self): """Init dumbq setup with its dependencies.""" self.init_hw_info() self.dumbq_setup = DumbqSetup(self.hardware_info, self.config, self.logger)
def init_dumbq_setup(self): """Init dumbq setup with its dependencies.""" self.init_hw_info() self.dumbq_setup = DumbqSetup( self.hardware_info, self.config, self.logger )