mirror of
https://github.com/MarioSpore/Grinch-AP.git
synced 2025-10-21 20:21:32 -06:00
MultiServer, customserver, CI, Test: Fix problems in room hosting and test/simulate it (#3464)
* Test: add hosting simulation test * WebHost: add weak typing to get_app() * MultiServer: add typing to auto_saver_thread * MultiServer: don't cancel task, properly end it * customserver: stop auto-save thread from saving after shutdown and make sure it stops, another potential memory leak * MultiServer, customserver: make datapackage small again * customserver: collect/finish room tasks Hopefully fixes the memory leak we are seeing * CI: test hosting * Test: hosting: verify autohoster saves on Ctrl+C * customserver: save when stopping via Ctrl+C
This commit is contained in:
75
test/hosting/generate.py
Normal file
75
test/hosting/generate.py
Normal file
@@ -0,0 +1,75 @@
|
||||
import json
|
||||
import sys
|
||||
import warnings
|
||||
from pathlib import Path
|
||||
from typing import Iterable, Union, TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from multiprocessing.managers import ListProxy # noqa
|
||||
|
||||
__all__ = [
|
||||
"generate_local",
|
||||
]
|
||||
|
||||
|
||||
def _generate_local_inner(games: Iterable[str],
|
||||
dest: Union[Path, str],
|
||||
results: "ListProxy[Union[Path, BaseException]]") -> None:
|
||||
original_argv = sys.argv
|
||||
warnings.simplefilter("ignore")
|
||||
try:
|
||||
from tempfile import TemporaryDirectory
|
||||
|
||||
if not isinstance(dest, Path):
|
||||
dest = Path(dest)
|
||||
|
||||
with TemporaryDirectory() as players_dir:
|
||||
with TemporaryDirectory() as output_dir:
|
||||
import Generate
|
||||
|
||||
for n, game in enumerate(games, 1):
|
||||
player_path = Path(players_dir) / f"{n}.yaml"
|
||||
with open(player_path, "w", encoding="utf-8") as f:
|
||||
f.write(json.dumps({
|
||||
"name": f"Player{n}",
|
||||
"game": game,
|
||||
game: {"hard_mode": "true"},
|
||||
"description": f"generate_local slot {n} ('Player{n}'): {game}",
|
||||
}))
|
||||
|
||||
# this is basically copied from test/programs/test_generate.py
|
||||
# uses a reproducible seed that is different for each set of games
|
||||
sys.argv = [sys.argv[0], "--seed", str(hash(tuple(games))),
|
||||
"--player_files_path", players_dir,
|
||||
"--outputpath", output_dir]
|
||||
Generate.main()
|
||||
output_files = list(Path(output_dir).glob('*.zip'))
|
||||
assert len(output_files) == 1
|
||||
final_file = dest / output_files[0].name
|
||||
output_files[0].rename(final_file)
|
||||
results.append(final_file)
|
||||
except BaseException as e:
|
||||
results.append(e)
|
||||
raise e
|
||||
finally:
|
||||
sys.argv = original_argv
|
||||
|
||||
|
||||
def generate_local(games: Iterable[str], dest: Union[Path, str]) -> Path:
|
||||
from multiprocessing import Manager, Process, set_start_method
|
||||
|
||||
try:
|
||||
set_start_method("spawn")
|
||||
except RuntimeError:
|
||||
pass
|
||||
|
||||
manager = Manager()
|
||||
results: "ListProxy[Union[Path, Exception]]" = manager.list()
|
||||
|
||||
p = Process(target=_generate_local_inner, args=(games, dest, results))
|
||||
p.start()
|
||||
p.join()
|
||||
result = results[0]
|
||||
if isinstance(result, BaseException):
|
||||
raise Exception("Could not generate multiworld") from result
|
||||
return result
|
Reference in New Issue
Block a user