From 26a6c1388ee134a3cceb1fad943119d24eb0c42b Mon Sep 17 00:00:00 2001 From: Paul Traylor Date: Wed, 7 Dec 2022 16:14:32 +0900 Subject: [PATCH 1/2] Update test_alert_rules Rewrite our alert rule tests to use our fixtures. This means that we no longer need to do as much setup in the individual test cases and can focus more on the specific logic we're testing. Because we're using a rule from a fixture, we also need to update our test template a bit. --- promgen/tests/test_alert_rules.py | 68 ++++++++++++------------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/promgen/tests/test_alert_rules.py b/promgen/tests/test_alert_rules.py index d42f90f09..ce45cc62e 100644 --- a/promgen/tests/test_alert_rules.py +++ b/promgen/tests/test_alert_rules.py @@ -14,14 +14,14 @@ groups: - name: promgen.example.com rules: - - alert: RuleName + - alert: example-rule annotations: - rule: https://promgen.example.com/rule/%d - summary: Test case - expr: up==0 + rule: https://promgen.example.com/rule/1 + summary: Example rule summary + expr: up==1 for: 1s labels: - severity: severe + severity: high """.lstrip().encode( "utf-8" ) @@ -30,39 +30,18 @@ class RuleTest(tests.PromgenTest): - @mock.patch("django.dispatch.dispatcher.Signal.send") - def setUp(self, mock_signal): - self.user = self.force_login(username="demo") - self.site = models.Site.objects.get_current() - self.shard = models.Shard.objects.create(name="Shard 1") - self.service = models.Service.objects.create(id=999, name="Service 1") - self.rule = models.Rule.objects.create( - name="RuleName", - clause="up==0", - duration="1s", - obj=self.site, - ) - models.RuleLabel.objects.create( - name="severity", - value="severe", - rule=self.rule, - ) - models.RuleAnnotation.objects.create( - name="summary", - value="Test case", - rule=self.rule, - ) + fixtures = ["testcases.yaml", "extras.yaml"] @override_settings(PROMGEN_SCHEME="https") @mock.patch("django.dispatch.dispatcher.Signal.send") def test_write_new(self, mock_post): result = prometheus.render_rules() - self.assertEqual(result, _RULE_V2 % self.rule.id) + self.assertEqual(result, _RULE_V2) @mock.patch("django.dispatch.dispatcher.Signal.send") def test_copy(self, mock_post): - service = models.Service.objects.create(name="Service 2") - copy = self.rule.copy_to(content_type="service", object_id=service.id) + rule = models.Rule.objects.get(pk=1) + copy = rule.copy_to(content_type="service", object_id=2) # Test that our copy has the same labels and annotations self.assertIn("severity", copy.labels) self.assertIn("summary", copy.annotations) @@ -77,6 +56,7 @@ def test_copy(self, mock_post): @override_settings(PROMGEN=TEST_SETTINGS) @mock.patch("django.dispatch.dispatcher.Signal.send") def test_import_v2(self, mock_post): + self.user = self.force_login(username="demo") self.add_user_permissions("promgen.change_rule", "promgen.change_site") response = self.client.post( reverse("rule-import"), @@ -93,12 +73,11 @@ def test_import_v2(self, mock_post): @override_settings(PROMGEN=TEST_SETTINGS) @mock.patch("django.dispatch.dispatcher.Signal.send") def test_import_project_rule(self, mock_post): + self.user = self.force_login(username="demo") self.add_user_permissions("promgen.add_rule", "promgen.change_project") - project = models.Project.objects.create( - name="Project 1", service=self.service, shard=self.shard - ) + response = self.client.post( - reverse("rule-new", kwargs={"content_type": "project", "object_id": project.id}), + reverse("rule-new", kwargs={"content_type": "project", "object_id": 1}), {"rules": tests.Data("examples", "import.rule.yml").raw()}, follow=True, ) @@ -110,11 +89,12 @@ def test_import_project_rule(self, mock_post): @override_settings(PROMGEN=TEST_SETTINGS) @mock.patch("django.dispatch.dispatcher.Signal.send") def test_import_service_rule(self, mock_post): + self.user = self.force_login(username="demo") self.add_user_permissions("promgen.add_rule", "promgen.change_service") response = self.client.post( reverse( "rule-new", - kwargs={"content_type": "service", "object_id": self.service.id}, + kwargs={"content_type": "service", "object_id": 1}, ), {"rules": tests.Data("examples", "import.rule.yml").raw()}, follow=True, @@ -136,15 +116,16 @@ def test_missing_permission(self, mock_post): @mock.patch("django.dispatch.dispatcher.Signal.send") def test_macro(self, mock_post): - self.project = models.Project.objects.create( - name="Project 1", service=self.service, shard=self.shard - ) + self.site = models.Site.objects.get(pk=1) + self.service = models.Service.objects.get(pk=1) + self.project = models.Project.objects.get(pk=1) + clause = "up{%s}" % macro.EXCLUSION_MACRO rules = { - "common": {"assert": 'up{service!~"Service 1"}'}, - "service": {"assert": 'up{service="Service 1",project!~"Project 1"}'}, - "project": {"assert": 'up{service="Service 1",project="Project 1",}'}, + "common": {"assert": 'up{service!~"test-service"}'}, + "service": {"assert": 'up{service="test-service",project!~"test-project"}'}, + "project": {"assert": 'up{service="test-service",project="test-project",}'}, } common_rule = models.Rule.objects.create( @@ -162,7 +143,8 @@ def test_macro(self, mock_post): @override_settings(PROMGEN=TEST_SETTINGS) @mock.patch("django.dispatch.dispatcher.Signal.send") def test_invalid_annotation(self, mock_post): + rule = models.Rule.objects.get(pk=1) # $label.foo is invalid (should be $labels) so make sure we raise an exception - models.RuleAnnotation.objects.create(name="summary", value="{{$label.foo}}", rule=self.rule) + models.RuleAnnotation.objects.create(name="summary", value="{{$label.foo}}", rule=rule) with self.assertRaises(ValidationError): - prometheus.check_rules([self.rule]) + prometheus.check_rules([rule]) From 8f7516ee4c0a301ebdfe7a47f7e6cdf7adc80891 Mon Sep 17 00:00:00 2001 From: Paul Traylor Date: Wed, 7 Dec 2022 16:16:44 +0900 Subject: [PATCH 2/2] Update test_cli Update our CLI tests to use our fixtures to ensure reproducible tests. We'll use cli- as a prefix for our objects to ensure they don't otherwise conflict with out fixture values. --- promgen/tests/test_cli.py | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/promgen/tests/test_cli.py b/promgen/tests/test_cli.py index a53d96212..5b49b5e11 100644 --- a/promgen/tests/test_cli.py +++ b/promgen/tests/test_cli.py @@ -11,46 +11,41 @@ class CLITests(PromgenTest): + fixtures = ["testcases.yaml", "extras.yaml"] + @mock.patch("promgen.signals._trigger_write_config") def test_register_job(self, mock_signal): # Assert when project doesn't exist with self.assertRaises(CommandError): management.call_command("register-job", "missing-project", "example", 1234) - # Create a Service and Project and then try adding our job - shard = models.Shard.objects.create(name="TestShard") - service = models.Service.objects.create(name="TestService") - _ = models.Project.objects.create(name="TestProject", service=service, shard=shard) - management.call_command("register-job", "TestProject", "example", 1234) + management.call_command("register-job", "test-project", "example", 1234) # Ensure the jobs we expect exist self.assertCount(models.Exporter, 1) # Registering the same job again shouldn't change our count - management.call_command("register-job", "TestProject", "example", 1234) + management.call_command("register-job", "test-project", "example", 1234) self.assertCount(models.Exporter, 1) # But registering a new one will - management.call_command("register-job", "TestProject", "example", 4321) + management.call_command("register-job", "test-project", "example", 4321) self.assertCount(models.Exporter, 2) @mock.patch("promgen.signals._trigger_write_config") def test_register_host(self, mock_signal): # Assert when project doesn't exist with self.assertRaises(CommandError): - management.call_command("register-host", "missing-project", "example.com") + management.call_command("register-host", "missing-project", "cli.example.com") - # Create a Service and Project and then try adding our job - shard = models.Shard.objects.create(name="TestShard") - service = models.Service.objects.create(name="TestService") - project = models.Project.objects.create(name="TestProject", service=service, shard=shard) + project = models.Project.objects.create(name="cli-project", service_id=1, shard_id=1) # Still assert an error if there is no Farm with self.assertRaises(CommandError): - management.call_command("register-host", "TestProject", "example.com") + management.call_command("register-host", "cli-project", "cli.example.com") # Register farm and finally register host - project.farm = models.Farm.objects.create(name="TestFarm") + project.farm = models.Farm.objects.create(name="cli-farm") project.save() - management.call_command("register-host", "TestProject", "example.com") - self.assertCount(models.Host, 1, "Should be a single host registered") + management.call_command("register-host", "cli-project", "cli.example.com") + self.assertCount(models.Host, 2, "Should be a new host registered (1 host from fixture)")