* Tests: Add a test that weights file generates different results per player correctly * Update test/programs/test_generate.py * Generate.main() return and accessibility options were changed
		
			
				
	
	
		
			140 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			140 lines
		
	
	
		
			6.0 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
# Tests for Generate.py (ArchipelagoGenerate.exe)
 | 
						|
 | 
						|
import unittest
 | 
						|
import os
 | 
						|
import os.path
 | 
						|
import sys
 | 
						|
 | 
						|
from pathlib import Path
 | 
						|
from tempfile import TemporaryDirectory
 | 
						|
 | 
						|
import Generate
 | 
						|
import Main
 | 
						|
 | 
						|
 | 
						|
class TestGenerateMain(unittest.TestCase):
 | 
						|
    """This tests Generate.py (ArchipelagoGenerate.exe) main"""
 | 
						|
 | 
						|
    generate_dir = Path(Generate.__file__).parent
 | 
						|
    run_dir = generate_dir / "test"  # reproducible cwd that's neither __file__ nor Generate.__file__
 | 
						|
    abs_input_dir = Path(__file__).parent / 'data' / 'one_player'
 | 
						|
    rel_input_dir = abs_input_dir.relative_to(run_dir)  # directly supplied relative paths are relative to cwd
 | 
						|
    yaml_input_dir = abs_input_dir.relative_to(generate_dir)  # yaml paths are relative to user_path
 | 
						|
 | 
						|
    def assertOutput(self, output_dir: str):
 | 
						|
        output_path = Path(output_dir)
 | 
						|
        output_files = list(output_path.glob('*.zip'))
 | 
						|
        if len(output_files) == 1:
 | 
						|
            return True
 | 
						|
        self.fail(f"Expected {output_dir} to contain one zip, but has {len(output_files)}: "
 | 
						|
                  f"{list(output_path.glob('*'))}")
 | 
						|
 | 
						|
    def setUp(self):
 | 
						|
        self.original_argv = sys.argv.copy()
 | 
						|
        self.original_cwd = os.getcwd()
 | 
						|
        self.original_local_path = Generate.Utils.local_path.cached_path
 | 
						|
        self.original_user_path = Generate.Utils.user_path.cached_path
 | 
						|
 | 
						|
        # Force both user_path and local_path to a specific path. They have independent caches.
 | 
						|
        Generate.Utils.user_path.cached_path = Generate.Utils.local_path.cached_path = str(self.generate_dir)
 | 
						|
        os.chdir(self.run_dir)
 | 
						|
        self.output_tempdir = TemporaryDirectory(prefix='AP_out_')
 | 
						|
 | 
						|
    def tearDown(self):
 | 
						|
        self.output_tempdir.cleanup()
 | 
						|
        os.chdir(self.original_cwd)
 | 
						|
        sys.argv = self.original_argv
 | 
						|
        Generate.Utils.local_path.cached_path = self.original_local_path
 | 
						|
        Generate.Utils.user_path.cached_path = self.original_user_path
 | 
						|
 | 
						|
    def test_paths(self):
 | 
						|
        self.assertTrue(os.path.exists(self.generate_dir))
 | 
						|
        self.assertTrue(os.path.exists(self.run_dir))
 | 
						|
        self.assertTrue(os.path.exists(self.abs_input_dir))
 | 
						|
        self.assertTrue(os.path.exists(self.rel_input_dir))
 | 
						|
        self.assertFalse(os.path.exists(self.yaml_input_dir))  # relative to user_path, not cwd
 | 
						|
 | 
						|
    def test_generate_absolute(self):
 | 
						|
        sys.argv = [sys.argv[0], '--seed', '0',
 | 
						|
                    '--player_files_path', str(self.abs_input_dir),
 | 
						|
                    '--outputpath', self.output_tempdir.name]
 | 
						|
        print(f'Testing Generate.py {sys.argv} in {os.getcwd()}')
 | 
						|
        Main.main(*Generate.main())
 | 
						|
 | 
						|
        self.assertOutput(self.output_tempdir.name)
 | 
						|
 | 
						|
    def test_generate_relative(self):
 | 
						|
        sys.argv = [sys.argv[0], '--seed', '0',
 | 
						|
                    '--player_files_path', str(self.rel_input_dir),
 | 
						|
                    '--outputpath', self.output_tempdir.name]
 | 
						|
        print(f'Testing Generate.py {sys.argv} in {os.getcwd()}')
 | 
						|
        Main.main(*Generate.main())
 | 
						|
 | 
						|
        self.assertOutput(self.output_tempdir.name)
 | 
						|
 | 
						|
    def test_generate_yaml(self):
 | 
						|
        # override host.yaml
 | 
						|
        from settings import get_settings
 | 
						|
        from Utils import user_path, local_path
 | 
						|
        settings = get_settings()
 | 
						|
        # NOTE: until/unless we override settings.Group's setattr, we have to upcast the input dir here
 | 
						|
        settings.generator.player_files_path = settings.generator.PlayerFilesPath(self.yaml_input_dir)
 | 
						|
        settings.generator.players = 0
 | 
						|
        settings._filename = None  # don't write to disk
 | 
						|
        user_path_backup = user_path.cached_path
 | 
						|
        user_path.cached_path = local_path()  # test yaml is actually in local_path
 | 
						|
        try:
 | 
						|
            sys.argv = [sys.argv[0], '--seed', '0',
 | 
						|
                        '--outputpath', self.output_tempdir.name]
 | 
						|
            print(f'Testing Generate.py {sys.argv} in {os.getcwd()}, player_files_path={self.yaml_input_dir}')
 | 
						|
            Main.main(*Generate.main())
 | 
						|
        finally:
 | 
						|
            user_path.cached_path = user_path_backup
 | 
						|
 | 
						|
        self.assertOutput(self.output_tempdir.name)
 | 
						|
 | 
						|
 | 
						|
class TestGenerateWeights(TestGenerateMain):
 | 
						|
    """Tests Generate.py using a weighted file to generate for multiple players."""
 | 
						|
 | 
						|
    # this test will probably break if something in generation is changed that affects the seed before the weights get processed
 | 
						|
    # can be fixed by changing the expected_results dict
 | 
						|
    generate_dir = TestGenerateMain.generate_dir
 | 
						|
    run_dir = TestGenerateMain.run_dir
 | 
						|
    abs_input_dir = Path(__file__).parent / "data" / "weights"
 | 
						|
    rel_input_dir = abs_input_dir.relative_to(run_dir)  # directly supplied relative paths are relative to cwd
 | 
						|
    yaml_input_dir = abs_input_dir.relative_to(generate_dir)  # yaml paths are relative to user_path
 | 
						|
 | 
						|
    # don't need to run these tests
 | 
						|
    test_generate_absolute = None
 | 
						|
    test_generate_relative = None
 | 
						|
 | 
						|
    def test_generate_yaml(self):
 | 
						|
        from settings import get_settings
 | 
						|
        from Utils import user_path, local_path
 | 
						|
        settings = get_settings()
 | 
						|
        settings.generator.player_files_path = settings.generator.PlayerFilesPath(self.yaml_input_dir)
 | 
						|
        settings.generator.players = 5  # arbitrary number, should be enough
 | 
						|
        settings._filename = None
 | 
						|
        user_path_backup = user_path.cached_path
 | 
						|
        user_path.cached_path = local_path()
 | 
						|
        try:
 | 
						|
            sys.argv = [sys.argv[0], "--seed", "1"]
 | 
						|
            namespace, seed = Generate.main()
 | 
						|
        finally:
 | 
						|
            user_path.cached_path = user_path_backup
 | 
						|
 | 
						|
        # there's likely a better way to do this, but hardcode the results from seed 1 to ensure they're always this
 | 
						|
        expected_results = {
 | 
						|
            "accessibility": [0, 2, 0, 2, 2],
 | 
						|
            "progression_balancing": [0, 50, 99, 0, 50],
 | 
						|
        }
 | 
						|
 | 
						|
        self.assertEqual(seed, 1)
 | 
						|
        for option_name, results in expected_results.items():
 | 
						|
            for player, result in enumerate(results, 1):
 | 
						|
                self.assertEqual(
 | 
						|
                    result, getattr(namespace, option_name)[player].value,
 | 
						|
                    "Generated results from weights file did not match expected value."
 | 
						|
                )
 |