diff --git a/charms/tempest-k8s/charmcraft.yaml b/charms/tempest-k8s/charmcraft.yaml index 40b06c17..27de6024 100644 --- a/charms/tempest-k8s/charmcraft.yaml +++ b/charms/tempest-k8s/charmcraft.yaml @@ -74,11 +74,15 @@ config: options: schedule: type: string - default: "" + default: "0 */1 * * *" description: | The cron schedule expression to define when to run tempest periodic checks. - When the value is empty (default), period checks will be disabled. + The value will only take effect when 'logging' relation is joined. Otherwise, + regardless of the value set, periodic checks are disabled. + + By default, tests will run every hour. When the value is set to empty, + periodic checks will be disabled. The cron implementation used is Vixie Cron, installed from Ubuntu main. For help with expressions, see `man 5 crontab` for Vixie Cron, diff --git a/charms/tempest-k8s/src/charm.py b/charms/tempest-k8s/src/charm.py index 04927b6d..87af0942 100755 --- a/charms/tempest-k8s/src/charm.py +++ b/charms/tempest-k8s/src/charm.py @@ -142,13 +142,11 @@ class TempestOperatorCharm(sunbeam_charm.OSBaseOperatorCharmK8S): if not schedule.valid: return "" - # if tempest env isn't ready, then we can't start scheduling tests - if not self.is_tempest_ready(): + # if tempest env isn't ready, or if the logging relation isn't joined + # then we can't start scheduling periodic tests + if not (self.is_tempest_ready() and self.loki.ready): return "" - # TODO: once observability integration is implemented, - # check if observability relations are ready here. - return schedule.value @property diff --git a/charms/tempest-k8s/src/handlers.py b/charms/tempest-k8s/src/handlers.py index db10355b..30305cd4 100644 --- a/charms/tempest-k8s/src/handlers.py +++ b/charms/tempest-k8s/src/handlers.py @@ -651,9 +651,33 @@ class LoggingRelationHandler(sunbeam_rhandlers.RelationHandler): } }, ) + + self.framework.observe( + interface.on.log_proxy_endpoint_joined, + self._on_log_proxy_endpoint_changed, + ) + self.framework.observe( + interface.on.log_proxy_endpoint_departed, + self._on_log_proxy_endpoint_changed, + ) + return interface + def _on_log_proxy_endpoint_changed(self, event): + if not self.model.unit.is_leader(): + return + + # to trigger context re-rendering + self.charm.configure_charm(event) + @property def ready(self) -> bool: - """Determine with the relation is ready for use.""" - return True + """Determine if the relation is ready for use.""" + try: + logger.info("Checking logging relation readiness...") + return bool( + self.interface._promtail_config("tempest").get("clients", []) + ) + except Exception as e: + logger.warning("Error getting loki client endpoints. %s", str(e)) + return False diff --git a/charms/tempest-k8s/tests/unit/test_tempest_charm.py b/charms/tempest-k8s/tests/unit/test_tempest_charm.py index 9cf20b0b..b7642d4c 100644 --- a/charms/tempest-k8s/tests/unit/test_tempest_charm.py +++ b/charms/tempest-k8s/tests/unit/test_tempest_charm.py @@ -177,6 +177,7 @@ class TestTempestOperatorCharm(test_utils.CharmTestCase): rel_id = harness.add_relation("logging", "loki") harness.add_relation_unit(rel_id, "loki/0") harness.charm.loki.interface = Mock() + harness.charm.loki.interface._promtail_config = Mock() return rel_id def add_grafana_dashboard_relation(self, harness): @@ -631,3 +632,30 @@ class TestTempestOperatorCharm(test_utils.CharmTestCase): def test_concurrency_calculation_more_cpus(self): """Test concurrency is bounded to 4.""" self.assertEqual(get_tempest_concurrency(), "4") + + def test_logging_ready(self): + """Test logging relation ready.""" + rel_id = self.add_logging_relation(self.harness) + + # client endpoints found + self.harness.charm.loki.interface._promtail_config.return_value = { + "clients": [ + { + "url": "http://grafana-agent-k8s-endpoints:3500/loki/api/v1/push" + } + ], + "other_key": "other_values", + } + self.assertEqual(self.harness.charm.loki.ready, True) + + # empty client endpoints + self.harness.charm.loki.interface._promtail_config.return_value = { + "clients": [], + "other_key": "other_values", + } + self.assertEqual(self.harness.charm.loki.ready, False) + + # empty promtail config + self.harness.remove_relation(rel_id) + self.harness.charm.loki.interface._promtail_config.return_value = {} + self.assertEqual(self.harness.charm.loki.ready, False)