Exemple #1
0
 def test_should_be_able_to_create_a_new_instance_folder(
         self, reset_folder_structure):
     """Our test server instance should be able to create a new instance folder."""
     server_name = "TestServer1"
     settings = self.settings.copy()
     settings.server_instance_name = server_name
     instance = ServerInstance(settings)
     instance._new_server_folder()
     assert isdir(join(self.test_path, "__server__" + server_name))
Exemple #2
0
 def setup(self, request, class_reset_folder_structure, c_sc_stub):
     """TestCompileBat setup"""
     request.cls.test_path = test_folder_structure_path()
     server_instance_name = "training"
     sb = ServerBatSettings(
         server_title="ODK Training Server",
         server_port="2202",
         server_config_file_name="serverTraining.cfg",
         server_cfg_file_name="Arma3Training.cfg",
         server_max_mem="8192",
         server_flags="-filePatching -autoinit -enableHT")
     sc = c_sc_stub
     request.cls.settings = ServerInstanceSettings(
         server_instance_name=server_instance_name,
         bat_settings=sb,
         config_settings=sc,
         arma_folder=self.test_path,
         server_instance_root=self.test_path,
         mods_to_be_copied=["CBA_A3"],
         user_mods_list=["ace", "CBA_A3", "ODKAI"],
         server_mods_list=["AdvProp", "ODKMIN"],
     )
     request.cls.instance = ServerInstance(self.settings)
     self.instance._new_server_folder()
     self.instance._compile_bat_file()
     request.cls.compiled_bat = join(
         self.instance.get_server_instance_path(), "run_server.bat")
Exemple #3
0
 def hook_init_copy_replace(self, server_instance: ServerInstance, call_data: List[str]) -> None:
     """Put the mod in copied_mods folder and symlink everything from the original mod, then simulate a regular
     folder structure."""
     mod_name = call_data[2]
     target_mod_folder = join(server_instance.get_server_instance_path(), server_instance.S.copied_mod_folder_name,
                              "@{}".format(mod_name))
     self._do_op(mod_name, server_instance.S.arma_folder, target_mod_folder)
Exemple #4
0
    def setup(self, request, c_sc_stub, c_sb_stub,
              class_reset_folder_structure):
        """TestAModFixOdkailocal setup"""
        # prepare the local folder
        request.cls.test_path = test_folder_structure_path()
        local_folder = join(self.test_path, "local_odkai")
        mkdir(local_folder)
        touch(join(local_folder, "local_mod"), "this is a local mod")

        fix_settings = ModFixSettings(
            enabled_fixes=["odkai_local"],
            mod_fix_settings={"odkai_local_path": local_folder})
        settings = ServerInstanceSettings("test",
                                          c_sb_stub,
                                          c_sc_stub,
                                          user_mods_list=["ODKAI"],
                                          arma_folder=self.test_path,
                                          server_instance_root=self.test_path,
                                          fix_settings=fix_settings)
        request.cls.instance = ServerInstance(settings)
        self.instance._new_server_folder()
        self.instance._prepare_server_core()
        self.instance._start_op_on_mods("init", ["ODKAI"])
        request.cls.mod_folder = join(self.instance.get_server_instance_path(),
                                      self.instance.S.linked_mod_folder_name,
                                      "@ODKAI")
Exemple #5
0
 def setup(self, request, class_reset_folder_structure, c_sc_stub,
           c_sb_stub):
     """TestModFixCba setup"""
     request.cls.test_path = test_folder_structure_path()
     request.cls.custom_cba = join(self.test_path, "cba_settings.sqf")
     touch(self.custom_cba, "test")
     fix_settings = ModFixSettings(
         enabled_fixes=["cba_a3"],
         mod_fix_settings={"cba_settings": self.custom_cba})
     settings = ServerInstanceSettings("test",
                                       c_sb_stub,
                                       c_sc_stub,
                                       user_mods_list=["CBA_A3"],
                                       arma_folder=self.test_path,
                                       server_instance_root=self.test_path,
                                       fix_settings=fix_settings)
     request.cls.instance = ServerInstance(settings)
     self.instance._new_server_folder()
     self.instance._prepare_server_core()
     request.cls.mod_folder = join(self.instance.get_server_instance_path(),
                                   self.instance.S.linked_mod_folder_name,
                                   "@CBA_A3")
     request.cls.cba_settings = join(
         self.instance.get_server_instance_path(), "userconfig",
         "cba_settings.sqf")
 def _link_local_copy(self, server_instance: ServerInstance) -> None:
     """Actually link the local copy."""
     mod_folder = join(server_instance.get_server_instance_path(), server_instance.S.linked_mod_folder_name,
                       "@" + self.name)
     mod_fix_settings = server_instance.S.fix_settings.mod_fix_settings
     local_folder = abspath(mod_fix_settings["odkai_local_path"])
     symlink(local_folder, mod_folder)
 def hook_update_link_replace(self, server_instance: ServerInstance, call_data: List[str]) -> None:
     """Make sure the local copy is symlinked."""
     mod_folder = join(server_instance.get_server_instance_path(), server_instance.S.linked_mod_folder_name,
                       "@" + self.name)
     if islink(mod_folder):
         unlink(mod_folder)
     self._link_local_copy(server_instance)
Exemple #8
0
 def setup(self, request, class_reset_folder_structure, c_sc_stub):
     """TestServerInstanceInit setup"""
     server_name = "TestServer1"
     request.cls.test_path = test_folder_structure_path()
     sb = ServerBatSettings(
         server_title="ODK Training Server",
         server_port="2202",
         server_config_file_name="serverTraining.cfg",
         server_cfg_file_name="Arma3Training.cfg",
         server_max_mem="8192",
         server_flags="-filePatching -autoinit -enableHT")
     sc = c_sc_stub
     request.cls.settings = ServerInstanceSettings(
         server_instance_name=server_name,
         bat_settings=sb,
         config_settings=sc,
         arma_folder=self.test_path,
         server_instance_root=self.test_path,
         mods_to_be_copied=["CBA_A3"],
         user_mods_list=["ace", "CBA_A3", "ODKAI"],
         server_mods_list=["AdvProp", "ODKMIN"],
     )
     request.cls.instance = ServerInstance(self.settings)
     request.cls.instance_folder = self.instance.get_server_instance_path()
     # set up all needed spies
     with spy(self.instance._new_server_folder) as request.cls.new_server_fun, \
             spy(self.instance._check_mods) as request.cls.check_mods_fun, \
             spy(self.instance._prepare_server_core) as request.cls.prepare_server_fun, \
             spy(self.instance._start_op_on_mods) as request.cls.init_mods_fun, \
             spy(self.instance._link_keys) as request.cls.init_keys_fun, \
             spy(self.instance._compile_bat_file) as request.cls.compiled_bat_fun, \
             spy(self.instance._compile_config_file) as request.cls.compiled_config_fun:
         self.instance.init()
    def setup(self, request, reset_folder_structure, sc_stub, sb_stub, mocker):
        """TestACopyModFix setup"""
        class LinkModFix(ModFix):

            name = "ace"

            def hook_init_link_pre(self, server_instance, call_data) -> None:
                pass

        class CopyModFix(ModFix):

            name = "cba_a3"

            def hook_init_copy_pre(self, server_instance, call_data) -> None:
                pass

        request.cls.test_path = test_folder_structure_path()
        settings = ServerInstanceSettings(
            "test",
            sb_stub,
            sc_stub,
            user_mods_list=["cba_a3", "ace"],
            fix_settings=ModFixSettings(enabled_fixes=["cba_a3", "ace"]),
            arma_folder=self.test_path,
            server_instance_root=self.test_path)
        mocker.patch("odk_servermanager.modfix.register_fixes",
                     return_value=[CopyModFix(), LinkModFix()])
        request.cls.instance = ServerInstance(settings)
Exemple #10
0
 def hook_update_copy_replace(self, server_instance: ServerInstance, call_data: List[str]) -> None:
     """Exactly the same as the init_copy, but ensure the folder is deleted first, to start anew."""
     mod_name = call_data[2]
     target_mod_folder = join(server_instance.get_server_instance_path(), server_instance.S.copied_mod_folder_name,
                              "@{}".format(mod_name))
     if isdir(target_mod_folder):
         # Delete the old folder, it's better to start anew
         rmtree(target_mod_folder)
     self._do_op(mod_name, server_instance.S.arma_folder, target_mod_folder)
Exemple #11
0
 def manage_instance(self, config_file: str) -> None:
     """Offer a basic ui so that the user can distinguish between instance's init and update."""
     self.config_file = config_file
     print("\n ======[ WELCOME TO ODKSM! ]======\n")
     try:
         self._recover_settings()
         self.instance = ServerInstance(self.settings)
     except (NonExistingFixFile, MisconfiguredModFix) as err:
         self._ui_abort(
             "\n [ERR] Error while loading mod fix: {}\n Bye!\n".format(
                 err.args[0]))
     except Exception as err:
         self._ui_abort(
             "\n [ERR] Error while loading the configuration file.\n Something was wrong in the odksm "
             "config file or in the Arma 3 mod preset.\n\n {}\n\n "
             "Check the documentation in the wiki, in the README.md or in the "
             "odksm_servermanager/settings.py.\n Bye!\n".format(err))
     try:
         print("\n Loaded config file: {}\n Instance name: {}"
               "\n Server title: {}\n".format(
                   self.config_file, self.instance.S.server_instance_name,
                   self.instance.S.config_settings.hostname))
         if not self.instance.is_folder_instance_already_there():
             self._ui_init()
         else:
             self._ui_update()
     except ModNotFound as err:
         self._ui_abort(
             "\n [ERR] Error while loading mods: {}\n Bye!\n".format(
                 err.args[0]))
     except ErrorInModFix as err:
         self._ui_abort(
             "\n [ERR] Error while executing mod fix: {}\nYOUR SERVER INSTANCE MAY BE CORRUPTED! You "
             "should delete it and generate it again.\n Bye!\n".format(
                 err.args[0]))
     except Exception as err:
         self._ui_abort(
             "\n [ERR] Generic error.\n\n {}\n\n Please take notes on what you were doing and contact "
             "odksm team on github!\nYOUR SERVER INSTANCE MAY BE CORRUPTED! You should delete it and "
             "generate it again.\n Bye!\n".format(err))
Exemple #12
0
 def setup(self, request, class_reset_folder_structure, c_sc_stub,
           c_sb_stub):
     """TestAnInstanceWithANonExistingMod setup"""
     server_name = "TestServer1"
     request.cls.test_path = test_folder_structure_path()
     request.cls.settings = ServerInstanceSettings(
         server_name,
         c_sb_stub,
         c_sc_stub,
         user_mods_list=["NOT_THERE"],
         arma_folder=self.test_path,
         server_instance_root=self.test_path,
     )
     request.cls.instance = ServerInstance(self.settings)
Exemple #13
0
 def setup(self, request, sc_stub, sb_stub):
     """TestOurTestServerInstance setup"""
     server_name = "TestServer0"
     mods_to_be_copied = ["CBA_A3"]
     request.cls.test_path = test_folder_structure_path()
     request.cls.sb = sb_stub
     request.cls.sc = sc_stub
     request.cls.settings = ServerInstanceSettings(
         server_name,
         self.sb,
         self.sc,
         mods_to_be_copied=mods_to_be_copied,
         arma_folder=self.test_path,
         server_instance_root=self.test_path)
     request.cls.instance = ServerInstance(self.settings)
 def setup(self, request, reset_folder_structure, sc_stub, sb_stub):
     """TestAServerInstance setup"""
     request.cls.test_path = test_folder_structure_path()
     request.cls.enabled_fixes = ["cba_a3"]
     settings = ServerInstanceSettings(
         "test",
         sb_stub,
         sc_stub,
         user_mods_list=["ace"],
         fix_settings=ModFixSettings(enabled_fixes=self.enabled_fixes),
         arma_folder=self.test_path,
         server_instance_root=self.test_path)
     request.cls.instance = ServerInstance(settings)
     self.instance._new_server_folder()
     self.instance._prepare_server_core()
     self.instance._copy_mod("CBA_A3")
Exemple #15
0
 def setup(self, request, c_sc_stub, c_sb_stub, class_reset_folder_structure):
     """TestAModfixGos setup"""
     request.cls.test_path = test_folder_structure_path()
     fix_settings = ModFixSettings(enabled_fixes=["gos"])
     settings = ServerInstanceSettings("test", c_sb_stub, c_sc_stub,
                                       user_mods_list=["G.O.S Dariyah", "G.O.S Al Rayak"],
                                       arma_folder=self.test_path,
                                       server_instance_root=self.test_path,
                                       fix_settings=fix_settings)
     request.cls.instance = ServerInstance(settings)
     self.instance._new_server_folder()
     self.instance._prepare_server_core()
     self.instance._start_op_on_mods("init", ["G.O.S Dariyah"])
     self.instance._start_op_on_mods("init", ["G.O.S Al Rayak"])
     request.cls.moda_folder = join(self.instance.get_server_instance_path(),
                                    self.instance.S.copied_mod_folder_name, "@G.O.S Dariyah")
     request.cls.modb_folder = join(self.instance.get_server_instance_path(),
                                    self.instance.S.copied_mod_folder_name, "@G.O.S Al Rayak")
Exemple #16
0
 def setup(self, request, class_reset_folder_structure, c_sb_stub):
     """TestWhenConfigComposingTheServerInstance setup"""
     request.cls.test_path = test_folder_structure_path()
     server_instance_name = "TestServer0"
     sc = ServerConfigSettings(hostname="TRAINING SERVER",
                               password="******",
                               password_admin="abc",
                               mission_template="mission.name")
     request.cls.settings = ServerInstanceSettings(
         server_instance_name=server_instance_name,
         bat_settings=c_sb_stub,
         config_settings=sc,
         arma_folder=self.test_path,
         server_instance_root=self.test_path,
         mods_to_be_copied=["CBA_A3"],
         user_mods_list=["ace", "CBA_A3", "ODKAI"],
         server_mods_list=["AdvProp", "ODKMIN"],
     )
     request.cls.instance = ServerInstance(self.settings)
     self.instance._compile_config_file()
     request.cls.compiled_config = join(
         self.instance.get_server_instance_path(),
         self.instance.S.bat_settings.server_config_file_name)
Exemple #17
0
class ServerManager:

    settings: ServerInstanceSettings
    instance: ServerInstance
    config_file: str

    def __init__(self, debug_logs_path: Union[str, None] = None):
        self.debug_logs_path = debug_logs_path

    def bootstrap(self, default_config_file: str = None) -> None:
        """Interactive UI to start building a new server instance."""
        print("\n ======[ WELCOME TO ODKSM! ]======\n")
        try:
            # try and read the config
            data = ConfigIni.read_file(default_config_file, bootstrap=True)
            # check for needed fields
            if data["bootstrap"].get("instances_root", "") == "":
                raise ValueError(
                    "'instances_root' field can't be empty in the [bootstrap] section!"
                )
            if data["bootstrap"].get("odksm_folder_path", "") == "":
                raise ValueError(
                    "'odksm_folder_path' field can't be empty in the [bootstrap] section!"
                )
        except Exception as err:
            self._ui_abort(
                "\n [ERR] Error while reading the default config file!\n\n {}\n\n "
                "Check the documentation in the wiki, in the bootstrap.ini example file, in the README.md or"
                " in the odksm_servermanager/settings.py.\n Bye!\n".format(
                    err))
        try:
            # Check the instances_root exists
            instances_root = data["bootstrap"]["instances_root"]
            if not isdir(instances_root):
                raise Exception(
                    "Could not find the instances_folder '{}'".format(
                        instances_root))
            print(
                "\n This utility will help you start creating your server instance.\n"
            )
            instance_name = input(" Choose a unique name for the instance: ")
            # check if custom templates are needed
            custom_bat_template_needed = False
            custom_config_template_needed = False
            custom_templates_needed_string = input(
                " Will you need custom templates? (y/n) ")
            if custom_templates_needed_string == "y":
                print("\n OK! Now.. \n")
                custom_bat_template_needed_string = input(
                    " ... will you need a custom BAT template? (y/n) ")
                if custom_bat_template_needed_string == "y":
                    custom_bat_template_needed = True
                custom_config_template_needed_string = input(
                    " ... will you need a custom CONFIG template? (y/n) ")
                if custom_config_template_needed_string == "y":
                    custom_config_template_needed = True
            # create the folder
            instance_dir = join(instances_root, instance_name)
            mkdir(instance_dir)
            # copy templates if needed
            if custom_bat_template_needed:
                bat_template_file_name = "run_server_template.txt"
                bat_template_file = join(instance_dir, bat_template_file_name)
                template_file = self._get_resource_file(
                    "templates/{}".format(bat_template_file_name))
                copy(template_file, bat_template_file)
                data["bat"]["bat_template"] = abspath(bat_template_file)
            if custom_config_template_needed:
                config_template_file_name = "server_cfg_template.txt"
                config_template_file = join(instance_dir,
                                            config_template_file_name)
                template_file = self._get_resource_file(
                    "templates/{}".format(config_template_file_name))
                copy(template_file, config_template_file)
                data["config"]["config_template"] = abspath(
                    config_template_file)
            # prepare some fields for the config file
            data["ODKSM"]["server_instance_name"] = instance_name
            data["ODKSM"]["server_instance_root"] = abspath(instance_dir)
            # generate the config.ini file
            ConfigIni().create_file(join(instance_dir, "config.ini"), data)
            # compile the ODKSM.bat file
            bat_template = pkg_resources.resource_string(
                "odk_servermanager",
                "templates/ODKSM_bat_template.txt").decode("UTF-8")
            bat_file = join(instance_dir, "ODKSM.bat")
            compile_from_template(
                bat_template, bat_file,
                {"odksm_folder_path": data["bootstrap"]["odksm_folder_path"]})
            print(
                "\n Instance folder created!\n\n [WARNING] IMPORTANT! YOU ARE NOT DONE! You still need to edit the\n"
                " config.ini file in the folder and to run the actual ODKSM.bat tool.\n Bye!\n"
            )
        except Exception as err:
            self._ui_abort(
                "\n [ERR] Error while bootstrapping the instance!\n\n {}\n\n "
                "Check the documentation in the wiki, in the bootstrap.ini example file, in the README.md or"
                " in the odksm_servermanager/settings.py.\n Bye!\n".format(
                    err))

    @staticmethod
    def _get_resource_file(file: str) -> str:
        """Return the actual file path of a resource file."""
        return pkg_resources.resource_filename('odk_servermanager', file)

    def manage_instance(self, config_file: str) -> None:
        """Offer a basic ui so that the user can distinguish between instance's init and update."""
        self.config_file = config_file
        print("\n ======[ WELCOME TO ODKSM! ]======\n")
        try:
            self._recover_settings()
            self.instance = ServerInstance(self.settings)
        except (NonExistingFixFile, MisconfiguredModFix) as err:
            self._ui_abort(
                "\n [ERR] Error while loading mod fix: {}\n Bye!\n".format(
                    err.args[0]))
        except Exception as err:
            self._ui_abort(
                "\n [ERR] Error while loading the configuration file.\n Something was wrong in the odksm "
                "config file or in the Arma 3 mod preset.\n\n {}\n\n "
                "Check the documentation in the wiki, in the README.md or in the "
                "odksm_servermanager/settings.py.\n Bye!\n".format(err))
        try:
            print("\n Loaded config file: {}\n Instance name: {}"
                  "\n Server title: {}\n".format(
                      self.config_file, self.instance.S.server_instance_name,
                      self.instance.S.config_settings.hostname))
            if not self.instance.is_folder_instance_already_there():
                self._ui_init()
            else:
                self._ui_update()
        except ModNotFound as err:
            self._ui_abort(
                "\n [ERR] Error while loading mods: {}\n Bye!\n".format(
                    err.args[0]))
        except ErrorInModFix as err:
            self._ui_abort(
                "\n [ERR] Error while executing mod fix: {}\nYOUR SERVER INSTANCE MAY BE CORRUPTED! You "
                "should delete it and generate it again.\n Bye!\n".format(
                    err.args[0]))
        except Exception as err:
            self._ui_abort(
                "\n [ERR] Generic error.\n\n {}\n\n Please take notes on what you were doing and contact "
                "odksm team on github!\nYOUR SERVER INSTANCE MAY BE CORRUPTED! You should delete it and "
                "generate it again.\n Bye!\n".format(err))

    def _ui_init(self):
        """UI to init an instance."""
        user_answer = input(" Do you want to continue? (y/n) ")
        if self._is_positive_answer(user_answer):
            print("\n > Starting server instance INIT for {}!".format(
                self.instance.S.server_instance_name))
            self.instance.init()
            self._ui_print_warnings()
            print("\n [OK] Init done! Bye!\n")
        else:
            self._ui_abort()

    def _ui_update(self):
        """UI to update an instance."""
        name = self.instance.S.server_instance_name
        answer = input(
            " [WARNING] A server instance called {} seems already present.\n Continuing will "
            "UPDATE the existing server instance. Be sure to understand everything this entails.\n\n"
            " Do you want to continue? (y/n) ".format(name))
        if self._is_positive_answer(answer):
            print("\n > Starting server instance UPDATE for {}!".format(name))
            self.instance.update()
            self._ui_print_warnings()
            print("\n [OK] Update done! Bye!\n\n")
        else:
            self._ui_abort()

    def _ui_print_warnings(self):
        """Print warnings if needed."""
        if len(self.instance.warnings) > 0:
            print("\n We got some warnings:")
            for warn in self.instance.warnings:
                print(" [WARN] {}".format(warn))

    def _ui_abort(self, message: str = "\n [ABORTED] Bye!\n") -> None:
        """Print the given message and quit the program."""
        if self.debug_logs_path is not None:
            self._print_debug_log()
        print(message)
        exit(1)

    @staticmethod
    def _is_positive_answer(answer: str) -> bool:
        """Parse the answer and return True if positive."""
        return answer.lower() == "y" or answer.lower() == "yes"

    def _recover_settings(self):
        """Recover all needed settings, including mods presets."""
        self._parse_config()
        if self.settings.user_mods_preset != "":
            mods = self._parse_mods_preset(self.settings.user_mods_preset)
            # do not use shorthand += here: there's a bug in Box that will break things
            self.settings.user_mods_list = self.settings.user_mods_list + mods

    def _parse_config(self) -> None:
        """Parse the config file and create all settings container object."""
        # Recover data in the file
        data = ConfigIni.read_file(self.config_file)
        # Create settings containers
        config_settings = ServerConfigSettings(**data["config"])
        bat_settings = ServerBatSettings(**data["bat"])
        enabled_fixes = []
        if "enabled_fixes" in data["mod_fix_settings"]:
            enabled_fixes = data["mod_fix_settings"].pop("enabled_fixes")
        fix_settings = ModFixSettings(
            enabled_fixes=enabled_fixes,
            mod_fix_settings=data["mod_fix_settings"])
        # create the global settings container
        self.settings = ServerInstanceSettings(**data["ODKSM"],
                                               bat_settings=bat_settings,
                                               config_settings=config_settings,
                                               fix_settings=fix_settings)
        # add missing mod_fix mods to mods_to_be_copied
        from odk_servermanager.modfix import register_fixes
        mod_fixes = register_fixes(fix_settings.enabled_fixes)
        for fix in mod_fixes:
            # Check that it's a required mod:
            if fix.name in self.settings.user_mods_list + self.settings.server_mods_list:
                copy_hooks = [
                    "hook_init_copy_pre", "hook_init_copy_replace",
                    "hook_init_copy_post", "hook_update_copy_pre",
                    "hook_update_copy_replace", "hook_update_copy_post"
                ]
                for copy_hook in copy_hooks:
                    # Check if there's a copy hook enabled...
                    if getattr(
                            fix, copy_hook
                    ) is not None and fix.name not in self.settings.mods_to_be_copied:
                        # ... if so, add the mod to mods_to_be_copied
                        self.settings.mods_to_be_copied.append(fix.name)

    def _parse_mods_preset(self, filename: str) -> List[str]:
        """Parse an Arma 3 preset and return the List of all selected mods names."""
        # Open the preset file and read its content
        with open(filename, "r", encoding='utf-8') as f:
            xml = f.read()
        # Parse the file and extract all mods names
        parsed_xml = BeautifulSoup(xml, 'html.parser')
        mods_data = parsed_xml.select("tr[data-type=\"ModContainer\"]")
        mods_name = list(
            map(
                lambda x: self._display_name_filter(
                    x.select_one("td[data-type=\"DisplayName\"]").text),
                mods_data))
        return mods_name

    @staticmethod
    def _display_name_filter(name: str) -> str:
        """Fix some display names peculiarities."""
        return name.replace(":", "-").replace("/", "-")

    def _print_debug_log(self):
        """Print in a log file the stacktrace."""
        if self.debug_logs_path is not None and self._are_in_exception():
            # Recover the traceback
            tb = traceback.format_exc()
            log_name = "odksm_{}.log".format(
                time.strftime("%Y%m%d_%H%M%S", time.gmtime()))
            log_file = join(self.debug_logs_path, log_name)
            with open(log_file, "w+") as log:
                log.write(tb)

    @staticmethod
    def _are_in_exception():
        """Return true if we are currently handling an exception"""
        return sys.exc_info() != (None, None, None)
 def _get_cba_path(instance: ServerInstance) -> str:
     """Return the path of the instance cba_settings."""
     return join(instance.get_server_instance_path(), "userconfig",
                 "cba_settings.sqf")
Exemple #19
0
 def test_should_save_its_config(self, sc_stub, sb_stub):
     """A server instance should save its config."""
     settings = ServerInstanceSettings("server0", sb_stub, sc_stub)
     instance = ServerInstance(settings)
     assert instance.S == settings