def test_index_manager_regenerate_indices_from_broken_state(self, *args): """ `regenerate_indices` should succeed and give us a working ElasticSearch when it runs and finds a broken state (eg. with an existing, incorrect index with the name of an alias). This can occur when ES restarts and an update signal is triggered before Richie had a chance to bootstrap ES. """ # Create a course and trigger a signal to index it. This will create a # broken "richie_test_courses" index course = CourseFactory(should_publish=True) apply_es_action_to_course(course.extended_object, "index", "en") self.assertIsNotNone(ES_INDICES_CLIENT.get("richie_test_courses")) # Call our `regenerate_indices command` creation_datetime = datetime(2010, 1, 1, tzinfo=timezone.utc) creation_string = creation_datetime.strftime("%Y-%m-%d-%Hh%Mm%S.%fs") with mock.patch.object(timezone, "now", return_value=creation_datetime): regenerate_indices(None) # No error was thrown, the courses index (like all others) was bootstrapped self.assertIsNotNone( ES_INDICES_CLIENT.get(f"richie_test_courses_{creation_string}")) # The expected alias is associated with the index self.assertEqual( list(ES_INDICES_CLIENT.get_alias("richie_test_courses").keys())[0], f"richie_test_courses_{creation_string}", )
def test_index_manager_regenerate_indices(self, *args): """ Make sure indices are created, aliases updated and old, no longer useful indices are pruned when the `regenerate_elasticsearch` function is called. """ # Create an unrelated index with an alias to make sure it is unaffected by our operations ES_INDICES_CLIENT.create(index="unrelated_index") ES_INDICES_CLIENT.put_alias(index="unrelated_index", name="unrelated_index_alias") self.assertIsNotNone( ES_INDICES_CLIENT.get("unrelated_index")["unrelated_index"]) self.assertEqual( list(ES_INDICES_CLIENT.get_alias("unrelated_index_alias").keys()) [0], "unrelated_index", ) # Create all our indices from scratch # Use a mocked timezone.now to check the names of our indices as they include a datetime creation1_datetime = datetime(2010, 1, 1, tzinfo=timezone.utc) creation1_string = creation1_datetime.strftime("%Y-%m-%d-%Hh%Mm%S.%fs") with mock.patch.object(timezone, "now", return_value=creation1_datetime): regenerate_indices(None) expected_indices = [ "richie_test_categories", "richie_test_courses", "richie_test_organizations", "richie_test_persons", ] # All indices were created and properly aliased for alias_name in expected_indices: new_index_name = f"{alias_name}_{creation1_string}" # The index is created self.assertIsNotNone( ES_INDICES_CLIENT.get(new_index_name)[new_index_name]) # The expected alias is associated with the index self.assertEqual( list(ES_INDICES_CLIENT.get_alias(alias_name).keys())[0], new_index_name) # Now regenerate the indices, replacing the ones we just created creation2_datetime = datetime(2011, 2, 2, tzinfo=timezone.utc) creation2_string = creation2_datetime.strftime("%Y-%m-%d-%Hh%Mm%S.%fs") with mock.patch.object(timezone, "now", return_value=creation2_datetime): regenerate_indices(None) # All indices were replaced and aliases updated for alias_name in expected_indices: # The index is created new_index_name = f"{alias_name}_{creation2_string}" self.assertIsNotNone( ES_INDICES_CLIENT.get(new_index_name)[new_index_name]) # The expected alias is associated with the new index self.assertEqual( list(ES_INDICES_CLIENT.get_alias(alias_name).keys())[0], new_index_name) # The previous version of the index is still around creation1_index_name = f"{alias_name}_{creation1_string}" self.assertIsNotNone( ES_INDICES_CLIENT.get(creation1_index_name) [creation1_index_name]) # But not aliased any more self.assertEqual( ES_INDICES_CLIENT.get(creation1_index_name) [creation1_index_name]["aliases"], {}, ) # Regenerate indices again to make sure versions n-2 of indices are # deleted (not just unaliased) creation3_datetime = datetime(2012, 3, 3, tzinfo=timezone.utc) creation3_string = creation3_datetime.strftime("%Y-%m-%d-%Hh%Mm%S.%fs") with mock.patch.object(timezone, "now", return_value=creation3_datetime): regenerate_indices(None) # All indices were replaced and had their aliases changed for index_name in expected_indices: new_index_name = f"{index_name}_{creation3_string}" # The index is created self.assertIsNotNone( ES_INDICES_CLIENT.get(new_index_name)[new_index_name]) # The expected alias is associated with the new index self.assertEqual( list(ES_INDICES_CLIENT.get_alias(index_name).keys())[0], new_index_name) # The previous version of the index is still around creation2_index_name = f"{alias_name}_{creation2_string}" self.assertIsNotNone( ES_INDICES_CLIENT.get(creation2_index_name) [creation2_index_name]) # But not aliased any more self.assertEqual( ES_INDICES_CLIENT.get(creation2_index_name) [creation2_index_name]["aliases"], {}, ) # Version n-2 of the index does not exist any more with self.assertRaises(NotFoundError): ES_INDICES_CLIENT.get(f"{index_name}_{creation1_string}") # Make sure our unrelated index was unaffected through regenerations self.assertIsNotNone( ES_INDICES_CLIENT.get("unrelated_index")["unrelated_index"]) self.assertEqual( list(ES_INDICES_CLIENT.get_alias("unrelated_index_alias").keys()) [0], "unrelated_index", )