From e77ebf059057b9c25778215a809b1697599f82af Mon Sep 17 00:00:00 2001 From: Boris Pavlovic Date: Sun, 23 Jul 2017 14:01:26 -0700 Subject: [PATCH] Ceilometer Samples Context should wait until samples are processed - Ceilometer doesn't process data imediatelly so it makes sense to wait until data is processed - Use UUID for resource ids - Reduce amount of resources that are created in CI for get_stas scenario Change-Id: I8b9da5aa31be705a60aeada2be86eda23c334448 --- rally-jobs/telemetry-neutron.yaml | 4 +-- .../openstack/context/ceilometer/samples.py | 26 ++++++++++++++++ .../openstack/scenarios/ceilometer/utils.py | 3 +- .../context/ceilometer/test_samples.py | 30 +++++++++++-------- .../scenarios/ceilometer/test_utils.py | 16 +++++----- 5 files changed, 55 insertions(+), 24 deletions(-) diff --git a/rally-jobs/telemetry-neutron.yaml b/rally-jobs/telemetry-neutron.yaml index 2d00497c..8491ee1e 100644 --- a/rally-jobs/telemetry-neutron.yaml +++ b/rally-jobs/telemetry-neutron.yaml @@ -380,8 +380,8 @@ counter_type: "gauge" counter_unit: "%" counter_volume: 100 - resources_per_tenant: 100 - samples_per_resource: 100 + resources_per_tenant: 5 + samples_per_resource: 5 timestamp_interval: 10 metadata_list: - diff --git a/rally/plugins/openstack/context/ceilometer/samples.py b/rally/plugins/openstack/context/ceilometer/samples.py index 65fff570..86d35094 100644 --- a/rally/plugins/openstack/context/ceilometer/samples.py +++ b/rally/plugins/openstack/context/ceilometer/samples.py @@ -12,6 +12,8 @@ # License for the specific language governing permissions and limitations # under the License. +import time + from six import moves from rally.common.i18n import _ @@ -115,6 +117,7 @@ class CeilometerSampleGenerator(context.Context): raise exceptions.ContextSetupFailure( ctx_name=self.get_name(), msg=_("Context failed to store too many batches of samples")) + return samples @logging.log_task_wrapper(LOG.info, _("Enter context: `Ceilometer`")) @@ -125,6 +128,8 @@ class CeilometerSampleGenerator(context.Context): "counter_unit": self.config["counter_unit"], "counter_volume": self.config["counter_volume"], } + resources = [] + for user, tenant_id in rutils.iterate_per_tenants( self.context["users"]): self.context["tenants"][tenant_id]["samples"] = [] @@ -148,6 +153,27 @@ class CeilometerSampleGenerator(context.Context): sample.to_dict()) self.context["tenants"][tenant_id]["resources"].append( samples[0].resource_id) + resources.append((user, samples[0].resource_id)) + + # NOTE(boris-42): Context should wait until samples are processed + from ceilometerclient import exc + + for user, resource_id in resources: + scenario = ceilo_utils.CeilometerScenario( + context={"user": user, "task": self.context["task"]}) + + success = False + for i in range(60): + try: + scenario._get_resource(resource_id) + success = True + break + except exc.HTTPNotFound: + time.sleep(3) + if not success: + raise exceptions.ContextSetupFailure( + ctx_name=self.get_name(), + msg="Ceilometer Resource %s is not found" % resource_id) @logging.log_task_wrapper(LOG.info, _("Exit context: `Ceilometer`")) def cleanup(self): diff --git a/rally/plugins/openstack/scenarios/ceilometer/utils.py b/rally/plugins/openstack/scenarios/ceilometer/utils.py index 74501749..3105eea7 100644 --- a/rally/plugins/openstack/scenarios/ceilometer/utils.py +++ b/rally/plugins/openstack/scenarios/ceilometer/utils.py @@ -13,6 +13,7 @@ # under the License. import datetime as dt +import uuid import six @@ -52,7 +53,7 @@ class CeilometerScenario(scenario.OpenStackScenario): "counter_type": counter_type, "counter_unit": counter_unit, "counter_volume": counter_volume, - "resource_id": self.generate_random_name() + "resource_id": str(uuid.uuid4()) } opt_fields = { "project_id": project_id, diff --git a/tests/unit/plugins/openstack/context/ceilometer/test_samples.py b/tests/unit/plugins/openstack/context/ceilometer/test_samples.py index d313f4c3..23ff6ae8 100644 --- a/tests/unit/plugins/openstack/context/ceilometer/test_samples.py +++ b/tests/unit/plugins/openstack/context/ceilometer/test_samples.py @@ -118,7 +118,14 @@ class CeilometerSampleGeneratorTestCase(test.TestCase): ceilometer_ctx._store_batch_samples, scenario, ["foo", "bar"], 1) - def test_setup(self): + @mock.patch("%s.samples.ceilo_utils.CeilometerScenario._get_resource" + % CTX) + @mock.patch("%s.samples.ceilo_utils.CeilometerScenario._create_samples" + % CTX) + @mock.patch( + "rally.plugins.openstack.scenarios.ceilometer.utils.uuid") + def test_setup(self, mock_uuid, mock_create_samples, mock_get_resource): + mock_uuid.uuid4.return_value = "fake_resource-id" tenants_count = 2 users_per_tenant = 2 resources_per_tenant = 2 @@ -142,8 +149,6 @@ class CeilometerSampleGeneratorTestCase(test.TestCase): "created_at": "2015-09-10T06:55:12.000000"} ] } - scenario.generate_random_name = mock.Mock( - return_value="fake_resource-id") kwargs = copy.deepcopy(sample) samples_to_create = list( scenario._make_samples(count=samples_per_resource, interval=60, @@ -158,16 +163,15 @@ class CeilometerSampleGeneratorTestCase(test.TestCase): new_context["tenants"][id_]["samples"].append(sample) new_context["tenants"][id_]["resources"].append( sample["resource_id"]) - with mock.patch("%s.samples.ceilo_utils.CeilometerScenario" - "._create_samples" % CTX) as mock_create_samples: - mock_create_samples.return_value = [] - for i, sample in enumerate(samples_to_create): - sample_object = mock.MagicMock(resource_id="fake_resource-id") - sample_object.to_dict.return_value = sample - mock_create_samples.return_value.append(sample_object) - ceilometer_ctx = samples.CeilometerSampleGenerator(real_context) - ceilometer_ctx.setup() - self.assertEqual(new_context, ceilometer_ctx.context) + + mock_create_samples.return_value = [] + for i, sample in enumerate(samples_to_create): + sample_object = mock.MagicMock(resource_id="fake_resource-id") + sample_object.to_dict.return_value = sample + mock_create_samples.return_value.append(sample_object) + ceilometer_ctx = samples.CeilometerSampleGenerator(real_context) + ceilometer_ctx.setup() + self.assertEqual(new_context, ceilometer_ctx.context) def test_cleanup(self): tenants, context = self._gen_context(2, 5, 3, 3) diff --git a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py index 4ee611bf..273a6059 100644 --- a/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py +++ b/tests/unit/plugins/openstack/scenarios/ceilometer/test_utils.py @@ -30,9 +30,9 @@ class CeilometerScenarioTestCase(test.ScenarioTestCase): super(CeilometerScenarioTestCase, self).setUp() self.scenario = utils.CeilometerScenario(self.context) - def test__make_samples_no_batch_size(self): - self.scenario.generate_random_name = mock.Mock( - return_value="fake_resource") + @mock.patch("%s.uuid.uuid4" % CEILOMETER_UTILS) + def test__make_samples_no_batch_size(self, mock_uuid4): + mock_uuid4.return_value = "fake_uuid" test_timestamp = dt.datetime(2015, 10, 20, 14, 18, 40) result = list(self.scenario._make_samples(count=2, interval=60, timestamp=test_timestamp)) @@ -41,16 +41,16 @@ class CeilometerScenarioTestCase(test.ScenarioTestCase): "counter_type": "gauge", "counter_unit": "%", "counter_volume": 1, - "resource_id": "fake_resource", + "resource_id": "fake_uuid", "timestamp": test_timestamp.isoformat()} self.assertEqual(expected, result[0][0]) samples_int = (parser.parse(result[0][0]["timestamp"]) - parser.parse(result[0][1]["timestamp"])).seconds self.assertEqual(60, samples_int) - def test__make_samples_batch_size(self): - self.scenario.generate_random_name = mock.Mock( - return_value="fake_resource") + @mock.patch("%s.uuid.uuid4" % CEILOMETER_UTILS) + def test__make_samples_batch_size(self, mock_uuid4): + mock_uuid4.return_value = "fake_uuid" test_timestamp = dt.datetime(2015, 10, 20, 14, 18, 40) result = list(self.scenario._make_samples(count=4, interval=60, batch_size=2, @@ -60,7 +60,7 @@ class CeilometerScenarioTestCase(test.ScenarioTestCase): "counter_type": "gauge", "counter_unit": "%", "counter_volume": 1, - "resource_id": "fake_resource", + "resource_id": "fake_uuid", "timestamp": test_timestamp.isoformat()} self.assertEqual(expected, result[0][0]) samples_int = (parser.parse(result[0][-1]["timestamp"]) -