diff --git a/esrally/driver/runner.py b/esrally/driver/runner.py index 4393da3d1..a36fca427 100644 --- a/esrally/driver/runner.py +++ b/esrally/driver/runner.py @@ -608,10 +608,15 @@ class IndicesStats(Runner): """ def _get(self, v, path): - if len(path) == 1: - return v[path[0]] + if v is None: + return None + elif len(path) == 1: + return v.get(path[0]) else: - return self._get(v[path[0]], path[1:]) + return self._get(v.get(path[0]), path[1:]) + + def _safe_string(self, v): + return str(v) if v is not None else None def __call__(self, es, params): index = params.get("index", "_all") @@ -628,8 +633,8 @@ def __call__(self, es, params): "condition": { "path": path, # avoid mapping issues in the ES metrics store by always rendering values as strings - "actual-value": str(actual_value), - "expected-value": str(expected_value) + "actual-value": self._safe_string(actual_value), + "expected-value": self._safe_string(expected_value) }, # currently we only support "==" as a predicate but that might change in the future "success": actual_value == expected_value diff --git a/tests/driver/runner_test.py b/tests/driver/runner_test.py index 5e57634fb..f6b3574c6 100644 --- a/tests/driver/runner_test.py +++ b/tests/driver/runner_test.py @@ -907,6 +907,39 @@ def test_indices_stats_with_successful_condition(self, es): es.indices.stats.assert_called_once_with(index="logs-*", metric="_all") + @mock.patch("elasticsearch.Elasticsearch") + def test_indices_stats_with_non_existing_path(self, es): + es.indices.stats.return_value = { + "indices": { + "total": { + "docs": { + "current": 0 + } + } + } + } + + indices_stats = runner.IndicesStats() + + result = indices_stats(es, params={ + "index": "logs-*", + "condition": { + # non-existing path + "path": "indices.my_index.total.docs.count", + "expected-value": 0 + } + }) + self.assertEqual(1, result["weight"]) + self.assertEqual("ops", result["unit"]) + self.assertFalse(result["success"]) + self.assertDictEqual({ + "path": "indices.my_index.total.docs.count", + "actual-value": None, + "expected-value": "0" + }, result["condition"]) + + es.indices.stats.assert_called_once_with(index="logs-*", metric="_all") + class QueryRunnerTests(TestCase): @mock.patch("elasticsearch.Elasticsearch")