async def test_keys_missing(test_environment: TestEnvironment) -> None: env: TestEnvironment = test_environment not_in_keychain_plots: List[Path] = get_test_plots("not_in_keychain") dir_not_in_keychain: TestDirectory = TestDirectory( env.root_path / "plots" / "not_in_keychain", not_in_keychain_plots ) expected_result = PlotRefreshResult() # The plots in "not_in_keychain" directory have infinity g1 elements as farmer/pool key so they should be plots # with missing keys for now add_plot_directory(env.root_path, str(dir_not_in_keychain.path)) expected_result.loaded = [] expected_result.removed = [] expected_result.processed = len(dir_not_in_keychain) expected_result.remaining = 0 for i in range(2): await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.no_key_filenames) == len(dir_not_in_keychain) for path in env.refresh_tester.plot_manager.no_key_filenames: assert path in dir_not_in_keychain.plots # Delete one of the plots and make sure it gets dropped from the no key filenames list drop_plot = dir_not_in_keychain.path_list()[0] dir_not_in_keychain.drop(drop_plot) drop_plot.unlink() assert drop_plot in env.refresh_tester.plot_manager.no_key_filenames expected_result.processed -= 1 await env.refresh_tester.run(expected_result) assert drop_plot not in env.refresh_tester.plot_manager.no_key_filenames # Now add the missing keys to the plot manager's key lists and make sure the plots are getting loaded env.refresh_tester.plot_manager.farmer_public_keys.append(G1Element()) env.refresh_tester.plot_manager.pool_public_keys.append(G1Element()) expected_result.loaded = dir_not_in_keychain.plot_info_list() # type: ignore[assignment] expected_result.processed = len(dir_not_in_keychain) await env.refresh_tester.run(expected_result) # And make sure they are dropped from the list of plots with missing keys assert len(env.refresh_tester.plot_manager.no_key_filenames) == 0
async def test_callback_event_raises(test_environment, event_to_raise: PlotRefreshEvents): last_event_fired: Optional[PlotRefreshEvents] = None def raising_callback(event: PlotRefreshEvents, _: PlotRefreshResult): nonlocal last_event_fired last_event_fired = event if event == event_to_raise: raise Exception(f"run_raise_in_callback {event_to_raise}") env: TestEnvironment = test_environment expected_result = PlotRefreshResult() # Load dir_1 add_plot_directory(env.root_path, str(env.dir_1.path)) expected_result.loaded = env.dir_1.plot_info_list( ) # type: ignore[assignment] expected_result.removed = [] expected_result.processed = len(env.dir_1) expected_result.remaining = 0 await env.refresh_tester.run(expected_result) # Load dir_2 add_plot_directory(env.root_path, str(env.dir_2.path)) expected_result.loaded = env.dir_2.plot_info_list( ) # type: ignore[assignment] expected_result.removed = [] expected_result.processed = len(env.dir_1) + len(env.dir_2) expected_result.remaining = 0 await env.refresh_tester.run(expected_result) # Now raise the exception in the callback default_callback = env.refresh_tester.plot_manager._refresh_callback env.refresh_tester.plot_manager.set_refresh_callback(raising_callback) env.refresh_tester.plot_manager.start_refreshing() env.refresh_tester.plot_manager.trigger_refresh() await time_out_assert(5, env.refresh_tester.plot_manager.needs_refresh, value=False) # And make sure the follow-up evens aren't fired assert last_event_fired == event_to_raise # The exception should trigger `PlotManager.reset()` and clear the plots assert len(env.refresh_tester.plot_manager.plots) == 0 assert len(env.refresh_tester.plot_manager.plot_filename_paths) == 0 assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 0 assert len(env.refresh_tester.plot_manager.no_key_filenames) == 0 # The next run without the valid callback should lead to re-loading of all plot env.refresh_tester.plot_manager.set_refresh_callback(default_callback) expected_result.loaded = env.dir_1.plot_info_list( ) + env.dir_2.plot_info_list() # type: ignore[assignment] expected_result.removed = [] expected_result.processed = len(env.dir_1) + len(env.dir_2) expected_result.remaining = 0 await env.refresh_tester.run(expected_result)
async def test_invalid_plots(test_environment): env: TestEnvironment = test_environment expected_result = PlotRefreshResult() # Test re-trying if processing a plot failed # First create a backup of the plot retry_test_plot = env.dir_1.path_list()[0].resolve() retry_test_plot_save = Path(env.dir_1.path / ".backup").resolve() copy(retry_test_plot, retry_test_plot_save) # Invalidate the plot with open(retry_test_plot, "r+b") as file: file.write(bytes(100)) # Add it and validate it fails to load add_plot_directory(env.root_path, str(env.dir_1.path)) expected_result.loaded = env.dir_1.plot_info_list()[1:] expected_result.removed = [] expected_result.processed = len(env.dir_1) expected_result.remaining = 0 await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 1 assert retry_test_plot in env.refresh_tester.plot_manager.failed_to_open_filenames # Give it a non .plot ending and make sure it gets removed from the invalid list on the next refresh retry_test_plot_unload = Path(env.dir_1.path / ".unload").resolve() move(retry_test_plot, retry_test_plot_unload) expected_result.processed -= 1 expected_result.loaded = [] await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 0 assert retry_test_plot not in env.refresh_tester.plot_manager.failed_to_open_filenames # Recover the name and make sure it reappears in the invalid list move(retry_test_plot_unload, retry_test_plot) expected_result.processed += 1 await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 1 assert retry_test_plot in env.refresh_tester.plot_manager.failed_to_open_filenames # Make sure the file stays in `failed_to_open_filenames` and doesn't get loaded in the next refresh cycle expected_result.loaded = [] expected_result.processed = len(env.dir_1) await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 1 assert retry_test_plot in env.refresh_tester.plot_manager.failed_to_open_filenames # Now decrease the re-try timeout, restore the valid plot file and make sure it properly loads now env.refresh_tester.plot_manager.refresh_parameter.retry_invalid_seconds = 0 move(retry_test_plot_save, retry_test_plot) expected_result.loaded = env.dir_1.plot_info_list()[0:1] expected_result.processed = len(env.dir_1) await env.refresh_tester.run(expected_result) assert len(env.refresh_tester.plot_manager.failed_to_open_filenames) == 0 assert retry_test_plot not in env.refresh_tester.plot_manager.failed_to_open_filenames
async def test_plot_info_caching(test_environment): env: TestEnvironment = test_environment expected_result = PlotRefreshResult() add_plot_directory(env.root_path, str(env.dir_1.path)) expected_result.loaded = env.dir_1.plot_info_list() expected_result.removed = [] expected_result.processed = len(env.dir_1) expected_result.remaining = 0 await env.refresh_tester.run(expected_result) assert env.refresh_tester.plot_manager.cache.path().exists() unlink(env.refresh_tester.plot_manager.cache.path()) # Should not write the cache again on shutdown because it didn't change assert not env.refresh_tester.plot_manager.cache.path().exists() env.refresh_tester.plot_manager.stop_refreshing() assert not env.refresh_tester.plot_manager.cache.path().exists() # Manually trigger `save_cache` and make sure it creates a new cache file env.refresh_tester.plot_manager.cache.save() assert env.refresh_tester.plot_manager.cache.path().exists() refresh_tester: PlotRefreshTester = PlotRefreshTester(env.root_path) plot_manager = refresh_tester.plot_manager plot_manager.cache.load() assert len(plot_manager.cache) == len(plot_manager.cache) await refresh_tester.run(expected_result) for path, plot_info in plot_manager.plots.items(): assert path in plot_manager.plots assert plot_manager.plots[path].prover.get_filename() == plot_info.prover.get_filename() assert plot_manager.plots[path].prover.get_id() == plot_info.prover.get_id() assert plot_manager.plots[path].prover.get_memo() == plot_info.prover.get_memo() assert plot_manager.plots[path].prover.get_size() == plot_info.prover.get_size() assert plot_manager.plots[path].pool_public_key == plot_info.pool_public_key assert plot_manager.plots[path].pool_contract_puzzle_hash == plot_info.pool_contract_puzzle_hash assert plot_manager.plots[path].plot_public_key == plot_info.plot_public_key assert plot_manager.plots[path].file_size == plot_info.file_size assert plot_manager.plots[path].time_modified == plot_info.time_modified assert plot_manager.plot_filename_paths == plot_manager.plot_filename_paths assert plot_manager.failed_to_open_filenames == plot_manager.failed_to_open_filenames assert plot_manager.no_key_filenames == plot_manager.no_key_filenames plot_manager.stop_refreshing() # Modify the content of the plot_manager.dat with open(plot_manager.cache.path(), "r+b") as file: file.write(b"\xff\xff") # Sets Cache.version to 65535 # Make sure it just loads the plots normally if it fails to load the cache refresh_tester: PlotRefreshTester = PlotRefreshTester(env.root_path) plot_manager = refresh_tester.plot_manager plot_manager.cache.load() assert len(plot_manager.cache) == 0 plot_manager.set_public_keys(bt.plot_manager.farmer_public_keys, bt.plot_manager.pool_public_keys) await refresh_tester.run(expected_result) assert len(plot_manager.plots) == len(plot_manager.plots) plot_manager.stop_refreshing()