def test__calling_importer_issues_rpc_calls_to_clusters(self): # Some clusters that we'll ask to import resources. rack_1 = factory.make_RackController() rack_2 = factory.make_RackController() # Connect only cluster #1. rack_1_conn = self.rpc.makeCluster(rack_1, ImportBootImages) rack_1_conn.ImportBootImages.return_value = succeed({}) # Do the import. importer = RackControllersImporter.new( [rack_1.system_id, rack_2.system_id]) results = importer(lock=DeferredLock()).wait(5) # The results are a list (it's from a DeferredList). self.assertThat( results, MatchesListwise(( # Success when calling rack_1. Equals((True, {})), # Failure when calling rack_1: no connection. MatchesListwise(( Is(False), MatchesAll( IsInstance(Failure), MatchesStructure( value=IsInstance(NoConnectionsAvailable)), ), )), )), )
def test__new_obtains_system_ids_for_accepted_clusters_if_not_given(self): rack = factory.make_RackController() importer = RackControllersImporter.new(sources=[], proxy=None) self.assertThat( importer, MatchesStructure(system_ids=Equals((rack.system_id, ))))
def test_new_obtains_None_proxy_if_disabled(self): # Disable boot source cache signals. self.addCleanup(bootsources.signals.enable) bootsources.signals.disable() proxy = factory.make_simple_http_url() Config.objects.set_config("http_proxy", proxy) Config.objects.set_config("enable_http_proxy", False) importer = RackControllersImporter.new(system_ids=[], sources=[]) self.assertThat(importer, MatchesStructure(proxy=Equals(None)))
def test__run_will_not_error_instead_it_logs(self): call = self.patch(RackControllersImporter, "__call__") call.return_value = fail(ZeroDivisionError()) with TwistedLoggerFixture() as logger: RackControllersImporter([], []).run().wait(5) self.assertThat(call, MockCalledOnceWith(ANY)) self.assertDocTestMatches( """\ General failure syncing boot resources. Traceback (most recent call last): ... """, logger.output)
def test__init_with_multiple_ssytem_ids(self): system_ids = [factory.make_name("system_id") for _ in range(3)] sources = [sentinel.source] proxy = factory.make_simple_http_url() importer = RackControllersImporter(system_ids, sources, proxy) self.assertThat( importer, MatchesStructure( system_ids=Equals(tuple(system_ids)), sources=Is(sources), proxy=Equals(urlparse(proxy)), ))
def test__init_with_single_system_id(self): system_id = factory.make_name("system_id") sources = [sentinel.source] proxy = factory.make_simple_http_url() importer = RackControllersImporter(system_id, sources, proxy) self.assertThat( importer, MatchesStructure( system_ids=Equals((system_id, )), sources=Is(sources), proxy=Equals(urlparse(proxy)), ))
def test_schedule_arranges_for_later_run(self): # Avoid deferring to the database. self.patch(boot_images_module, "deferToDatabase", maybeDeferred) # Avoid actually initiating a run. self.patch_autospec(RackControllersImporter, "run") system_ids = [factory.make_name("system_id") for _ in range(3)] sources = [sentinel.source] proxy = factory.make_simple_http_url() conc = random.randint(1, 9) delay = random.randint(1, 9) clock = Clock() delayed_call = RackControllersImporter.schedule( system_ids=system_ids, sources=sources, proxy=proxy, delay=delay, concurrency=conc, clock=clock, ) # The call is scheduled for `delay` seconds from now. self.assertThat(delayed_call, MatchesStructure(time=Equals(delay))) self.assertThat(RackControllersImporter.run, MockNotCalled()) clock.advance(delay) self.assertThat( RackControllersImporter.run, MockCalledOnceWith(ANY, conc) ) # The system_ids, sources, and proxy were all passed through. [importer, _] = RackControllersImporter.run.call_args[0] self.assertThat( importer, MatchesStructure( system_ids=Equals(tuple(system_ids)), sources=Is(sources), proxy=Equals(urlparse(proxy)), ), )
def test_run_calls_importer_and_reports_results(self): # Some clusters that we'll ask to import resources. rack_1 = factory.make_RackController() rack_2 = factory.make_RackController() rack_3 = factory.make_RackController() # Cluster #1 will work fine. cluster_1 = self.rpc.makeCluster(rack_1, ImportBootImages) cluster_1.ImportBootImages.return_value = succeed({}) # Cluster #2 will break. cluster_2 = self.rpc.makeCluster(rack_2, ImportBootImages) cluster_2.ImportBootImages.return_value = fail(ZeroDivisionError()) # Cluster #3 is not connected. # Do the import with reporting. importer = RackControllersImporter.new( [rack_1.system_id, rack_2.system_id, rack_3.system_id] ) with TwistedLoggerFixture() as logger: importer.run().wait(5) self.assertDocTestMatches( """\ ... --- Rack controller (%s) has imported boot resources. --- Rack controller (%s) failed to import boot resources. Traceback (most recent call last): ... --- Rack controller (%s) did not import boot resources; it is not connected to the region at this time. """ % (rack_1.system_id, rack_2.system_id, rack_3.system_id), logger.output, )
def test_new_obtains_sources_if_not_given(self): importer = RackControllersImporter.new(system_ids=[], proxy=None) self.assertThat( importer, MatchesStructure(sources=Equals([get_simplestream_endpoint()])), )
def test_new_obtains_system_ids_if_not_given(self): importer = RackControllersImporter.new(sources=[], proxy=None) self.assertThat(importer, MatchesStructure(system_ids=Equals(())))
def test_init_also_accepts_no_proxy(self): importer = RackControllersImporter( sentinel.system_id, [sentinel.source] ) self.assertThat(importer, MatchesStructure(proxy=Is(None)))
def test_init_also_accepts_already_parsed_proxy(self): proxy = urlparse(factory.make_simple_http_url()) importer = RackControllersImporter( sentinel.system_id, [sentinel.source], proxy ) self.assertThat(importer, MatchesStructure(proxy=Is(proxy)))