diff --git a/rally/benchmark/validation.py b/rally/benchmark/validation.py index 3d25f13644..8c0b1d7cae 100644 --- a/rally/benchmark/validation.py +++ b/rally/benchmark/validation.py @@ -371,3 +371,13 @@ def required_services(config, clients, task, *required_services): if service not in available_services: return ValidationResult( False, _("Service is not available: %s") % service) + + +@validator +def required_contexts(config, clients, task, *context_names): + missing_contexts = set(context_names) - set(config.get("context", {})) + if missing_contexts: + message = (_("The following contexts are required but missing from " + "the benchmark configuration file: %s") % + ", ".join(missing_contexts)) + return ValidationResult(False, message) diff --git a/tests/benchmark/test_validation.py b/tests/benchmark/test_validation.py index 668143bead..2071c4df96 100644 --- a/tests/benchmark/test_validation.py +++ b/tests/benchmark/test_validation.py @@ -80,6 +80,22 @@ class ValidationUtilsTestCase(test.TestCase): validator, = self._get_scenario_validators(func_failure, scenario) self.assertFalse(validator(None, None, None).is_valid) + def test_required_contexts(self): + config = {"context": {"context01": {}, "context02": {}}} + + required_contexts = (lambda *contexts: + validation.required_contexts(*contexts) + (lambda: None).validators.pop() + (config, None, None)) + + # All the required contexts are defined + result = required_contexts("context01", "context02") + self.assertTrue(result.is_valid) + + # A required context is not defined + result = required_contexts("context03") + self.assertFalse(result.is_valid) + def test_required_services(self): available_services = { consts.ServiceType.IDENTITY: consts.Service.KEYSTONE,