1
0
mirror of https://github.com/gryf/fs-uae-wrapper.git synced 2025-12-19 04:20:23 +01:00

Adjust existing cd32 module for base class

Fix failing tests for small changes in utils and cd32/base modules
This commit is contained in:
2017-01-01 17:31:40 +01:00
parent 47787a3ab2
commit fa7afcb73b
4 changed files with 61 additions and 176 deletions

View File

@@ -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()

View File

@@ -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:

View File

@@ -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

View File

@@ -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])