From fa7afcb73b48a76d1856cd96a49a9fed24f36c53 Mon Sep 17 00:00:00 2001 From: gryf Date: Sun, 1 Jan 2017 17:31:40 +0100 Subject: [PATCH] Adjust existing cd32 module for base class Fix failing tests for small changes in utils and cd32/base modules --- fs_uae_wrapper/cd32.py | 163 ++++++---------------------------------- fs_uae_wrapper/utils.py | 6 +- tests/test_cd32.py | 58 +++++++------- tests/test_utils.py | 10 +-- 4 files changed, 61 insertions(+), 176 deletions(-) diff --git a/fs_uae_wrapper/cd32.py b/fs_uae_wrapper/cd32.py index 903babb..b5526da 100644 --- a/fs_uae_wrapper/cd32.py +++ b/fs_uae_wrapper/cd32.py @@ -8,28 +8,18 @@ used as a base for save state (it will append '_save.7z' to the archive file name. """ -import os -import shutil import sys -import tempfile -from fs_uae_wrapper import utils +from fs_uae_wrapper import base -class CD32(object): +class CD32(base.Base): """ Class for performing extracting archive, copying emulator files, and cleaning it back again """ - def __init__(self): - self.dir = None - self.conf_file = None - self.save_filename = None - self.arch_filepath = None - self.all_options = None - self.fsuae_config = None - def run(self, conf_file, fs_uae_options, configuration): + def run(self): """ Main function which accepts configuration file for FS-UAE It will do as follows: @@ -39,26 +29,12 @@ class CD32(object): - [copy save if exists] - run the emulation - archive save state - - Params: - conf_file: a relative path to provided configuration file - fs_uae_options: is an CmdOption object created out of command line - parameters - configuration: is config dictionary created out of config file """ - self.all_options = utils.merge_all_options(configuration, - fs_uae_options) - - if 'wrapper_archive' not in self.all_options: - sys.stderr.write("Configuration lacks of required " - "`wrapper_archive' option.\n") + super(CD32, self).run() + if not self._validate_options(): return False - self.fsuae_config = configuration - self.conf_file = conf_file - self.dir = tempfile.mkdtemp() - - self.set_assets_paths() + self._set_assets_paths() if not self._extract(): return False @@ -66,131 +42,36 @@ class CD32(object): if not method(): return False - kick_opts = self.kickstart_option() + kick_opts = self._kickstart_option() if kick_opts: - fs_uae_options.update(kick_opts) + self.fsuae_options.update(kick_opts) - if self._run_game(fs_uae_options.list()): + if self._run_emulator(self.fsuae_options.list()): return self._save_save() return True - def clean(self): - """Remove temporary file""" - if self.dir: - shutil.rmtree(self.dir) - return + def _validate_options(self): + validation_result = super(CD32, self)._validate_options() - def kickstart_option(self): - """ - This is kind of hack - since we potentially can have a relative path - to kickstart directory, there is a need for getting this option from - configuration files (which unfortunately can be spanned all over the - different places, see https://fs-uae.net/configuration-files) and - check whether or not one of 'kickstarts_dir', 'kickstart_file' or - 'kickstart_ext_file' options are set. In either case if one of those - options are set and are relative, they should be set to absolute path, - so that kickstart files can be found by relocated configuration file. - """ + validation_result = True - conf = utils.get_config(self.conf_file) + if not super(CD32, self)._validate_options(): + validation_result = False - kick = {} + if 'wrapper_archive' not in self.all_options: + sys.stderr.write("Configuration lacks of required " + "`wrapper_archive' option.\n") + validation_result = False - for key in ('kickstart_file', 'kickstart_ext_file', 'kickstarts_dir'): - val = conf.get(key) - if val: - if not os.path.isabs(val): - val = utils.interpolate_variables(val, self.conf_file) - kick[key] = os.path.abspath(val) - else: - kick[key] = val - - return kick - - def set_assets_paths(self): - """ - Set full paths for archive file (without extension) and for save state - archive file - """ - conf_abs_dir = os.path.dirname(os.path.abspath(self.conf_file)) - conf_base = os.path.basename(self.conf_file) - conf_base = os.path.splitext(conf_base)[0] - - arch = self.all_options['wrapper_archive'] - if os.path.isabs(arch): - self.arch_filepath = arch - else: - self.arch_filepath = os.path.join(conf_abs_dir, arch) - self.save_filename = os.path.join(conf_abs_dir, conf_base + '_save.7z') - - def _copy_conf(self): - """copy provided configuration as Config.fs-uae""" - shutil.copy(self.conf_file, self.dir) - os.rename(os.path.join(self.dir, os.path.basename(self.conf_file)), - os.path.join(self.dir, 'Config.fs-uae')) - return True - - def _extract(self): - """Extract archive to temp dir""" - - item = self.all_options.get('title') - if not item: - item = self.all_options['wrapper_archive'] - - curdir = os.path.abspath('.') - os.chdir(self.dir) - result = utils.extract_archive(self.arch_filepath, - self.all_options.get('wrapper_gui_msg'), - item) - os.chdir(curdir) - return result - - def _run_game(self, fs_uae_options): - """execute game in provided directory""" - curdir = os.path.abspath('.') - os.chdir(self.dir) - utils.run_command(['fs-uae'] + fs_uae_options) - os.chdir(curdir) - return True - - def _save_save(self): - """ - Get the saves from emulator and store it where configuration is placed - """ - save_path = os.path.join(self.dir, 'fs-uae-save') - if not os.path.exists(save_path): - return True - - if os.path.exists(self.save_filename): - os.unlink(self.save_filename) - - if not utils.run_command(['7z', 'a', self.save_filename, - os.path.join(self.dir, 'fs-uae-save')]): - sys.stderr.write('Error: archiving save state failed\n') - return False - - return True - - def _load_save(self): - """ - Put the saves (if exists) to the temp directory. - """ - if not os.path.exists(self.save_filename): - return True - - curdir = os.path.abspath('.') - os.chdir(self.dir) - utils.run_command(['7z', 'x', self.save_filename]) - os.chdir(curdir) - return True + return validation_result -def run(config_file, fs_uae_options, configuration): +def run(config_file, fsuae_options, configuration): """Run fs-uae with provided config file and options""" - runner = CD32() + runner = CD32(config_file, fsuae_options, configuration) try: - return runner.run(config_file, fs_uae_options, configuration) + return runner.run() finally: runner.clean() diff --git a/fs_uae_wrapper/utils.py b/fs_uae_wrapper/utils.py index 41405d2..b11b14c 100644 --- a/fs_uae_wrapper/utils.py +++ b/fs_uae_wrapper/utils.py @@ -68,7 +68,7 @@ def get_config_options(conf): for key, val in parser.items(section)} -def extract_archive(arch_name, show_gui_message, message_text): +def extract_archive(arch_name, title=''): """ Extract provided archive to current directory """ @@ -86,8 +86,8 @@ def extract_archive(arch_name, show_gui_message, message_text): return False msg = message.Message("Extracting files for `%s'. Please be " - "patient" % message_text) - if show_gui_message == '1': + "patient" % title) + if title: msg.show() try: diff --git a/tests/test_cd32.py b/tests/test_cd32.py index 5e299d4..4a1cee3 100644 --- a/tests/test_cd32.py +++ b/tests/test_cd32.py @@ -10,6 +10,7 @@ except ImportError: import mock from fs_uae_wrapper import cd32 +from fs_uae_wrapper import utils class TestCD32(TestCase): @@ -38,7 +39,7 @@ class TestCD32(TestCase): def test_clean(self): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.clean() self.assertTrue(os.path.exists(self.dirname)) @@ -49,46 +50,46 @@ class TestCD32(TestCase): @mock.patch('fs_uae_wrapper.utils.get_config') def test_kickstart_option(self, get_config): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) get_config.return_value = {'foo': 'bar'} - self.assertDictEqual(acd32.kickstart_option(), {}) + self.assertDictEqual(acd32._kickstart_option(), {}) get_config.return_value = {'kickstarts_dir': '/some/path'} - self.assertDictEqual(acd32.kickstart_option(), + self.assertDictEqual(acd32._kickstart_option(), {'kickstarts_dir': '/some/path'}) os.chdir(self.dirname) get_config.return_value = {'kickstarts_dir': '../some/path'} result = os.path.abspath(os.path.join(self.dirname, '../some/path')) - self.assertDictEqual(acd32.kickstart_option(), + self.assertDictEqual(acd32._kickstart_option(), {'kickstarts_dir': result}) acd32.conf_file = os.path.join(self.dirname, 'Config.fs-uae') get_config.return_value = {'kickstarts_dir': '$CONFIG/../path'} result = os.path.abspath(os.path.join(self.dirname, '../path')) - self.assertDictEqual(acd32.kickstart_option(), + self.assertDictEqual(acd32._kickstart_option(), {'kickstarts_dir': result}) def test_set_assets_paths(self): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) os.chdir(self.dirname) acd32.conf_file = 'Config.fs-uae' acd32.all_options = {'wrapper_archive': 'foo.7z'} - acd32.set_assets_paths() + acd32._set_assets_paths() full_path = os.path.join(self.dirname, 'Config_save.7z') self.assertEqual(acd32.save_filename, full_path) acd32.all_options = {'wrapper_archive': '/home/user/foo.7z'} - acd32.set_assets_paths() + acd32._set_assets_paths() full_path = os.path.join(self.dirname, 'Config_save.7z') self.assertEqual(acd32.save_filename, full_path) def test_copy_conf(self): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.conf_file = self.fname acd32.dir = self.dirname @@ -99,7 +100,7 @@ class TestCD32(TestCase): @mock.patch('fs_uae_wrapper.utils.extract_archive') def test_extract(self, utils_extract): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.arch_filepath = self.fname acd32.dir = self.dirname @@ -107,47 +108,52 @@ class TestCD32(TestCase): # message for the gui is taken from title in fs-uae conf or, if there # is no such entry, use archive name, which is mandatory to provide - acd32.all_options = {'title': 'foo_game'} + acd32.all_options = {'title': 'foo_game', + 'wrapper_gui_msg': '1'} self.assertFalse(acd32._extract()) - utils_extract.assert_called_once_with(self.fname, None, 'foo_game') + utils_extract.assert_called_once_with(self.fname, 'foo_game') utils_extract.reset_mock() - acd32.all_options = {'wrapper_archive': 'arch.7z'} + acd32.all_options = {'wrapper_archive': 'arch.tar', + 'wrapper_gui_msg': '1'} self.assertFalse(acd32._extract()) - utils_extract.assert_called_once_with(self.fname, None, 'arch.7z') + utils_extract.assert_called_once_with(self.fname, 'arch.tar') - # lets pretend, the extracting has succeed. + # lets pretend, the extracting has failed utils_extract.reset_mock() - acd32.all_options['wrapper_gui_msg'] = '1' + acd32.all_options = {'wrapper_gui_msg': '0'} utils_extract.return_value = False self.assertFalse(acd32._extract()) - utils_extract.assert_called_once_with(self.fname, '1', 'arch.7z') + utils_extract.assert_called_once_with(self.fname, '') @mock.patch('fs_uae_wrapper.utils.run_command') - def test_run_game(self, run): + def test_run_emulator(self, run): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.dir = self.dirname - self.assertTrue(acd32._run_game([])) + self.assertTrue(acd32._run_emulator([])) run.assert_called_once_with(['fs-uae']) # Errors from emulator are not fatal to wrappers run.reset_mock() run.return_value = False - self.assertTrue(acd32._run_game([])) + self.assertTrue(acd32._run_emulator([])) run.assert_called_once_with(['fs-uae']) + @mock.patch('fs_uae_wrapper.base.Base._get_saves_dir') @mock.patch('fs_uae_wrapper.utils.run_command') - def test_save_save(self, run): + def test_save_save(self, run, saves_dir): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.dir = self.dirname - acd32.save_filename = "foobar_save.7z" + acd32.save_filename = 'foobar_save.7z' + saves_dir.acd32.save_filenamereturn_value = None run.return_value = True self.assertTrue(acd32._save_save()) + saves_dir.return_value = acd32.save_filename os.chdir(self.confdir) with open(acd32.save_filename, 'w') as fobj: fobj.write('asd') @@ -163,7 +169,7 @@ class TestCD32(TestCase): @mock.patch('fs_uae_wrapper.utils.run_command') def test_load_save(self, run): - acd32 = cd32.CD32() + acd32 = cd32.CD32('Config.fs-uae', utils.CmdOption(), {}) acd32.dir = self.dirname acd32.save_filename = "foobar_save.7z" run.return_value = 0 diff --git a/tests/test_utils.py b/tests/test_utils.py index 4c1d672..dedf827 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -77,21 +77,19 @@ class TestUtils(TestCase): os.chdir(self.dirname) # No config - self.assertFalse(utils.extract_archive('non-existend.7z', False, '')) + self.assertFalse(utils.extract_archive('non-existend.7z')) # Archive type not known with open('unsupported-archive.ace', 'w') as fobj: fobj.write("\n") - self.assertFalse(utils.extract_archive('unsupported-archive.ace', - False, '')) + self.assertFalse(utils.extract_archive('unsupported-archive.ace')) # archive is known, but extraction will fail - we have an empty # archive and there is no guarantee, that 7z exists on system where # test will run with open('supported-archive.7z', 'w') as fobj: fobj.write("\n") - self.assertFalse(utils.extract_archive('supported-archive.7z', - False, '')) + self.assertFalse(utils.extract_archive('supported-archive.7z')) @mock.patch('subprocess.check_call') def test_extract_archive_positive(self, sp_check_call): @@ -101,7 +99,7 @@ class TestUtils(TestCase): arch_name = 'archive.7z' with open(arch_name, 'w') as fobj: fobj.write("\n") - self.assertTrue(utils.extract_archive(arch_name, False, '')) + self.assertTrue(utils.extract_archive(arch_name)) sp_check_call.assert_called_once_with(utils.ARCHIVERS['.7z'] + [arch_name])