diff --git a/monasca_persister/repositories/influxdb/abstract_repository.py b/monasca_persister/repositories/influxdb/abstract_repository.py index fad54070..2e851420 100644 --- a/monasca_persister/repositories/influxdb/abstract_repository.py +++ b/monasca_persister/repositories/influxdb/abstract_repository.py @@ -57,8 +57,9 @@ class AbstractInfluxdbRepository(abstract_repository.AbstractRepository): database=database) break except influxdb.exceptions.InfluxDBClientError as ex: - if (str(ex).startswith(DATABASE_NOT_FOUND_MSG) and - self.conf.influxdb.db_per_tenant): + # When a databse is not found, the returned exception resolves + # to: {"error":"database not found: \"test\""} + if DATABASE_NOT_FOUND_MSG in str(ex): self._influxdb_client.create_database(database) else: raise diff --git a/monasca_persister/tests/test_influxdb_metrics_repository.py b/monasca_persister/tests/test_influxdb_metrics_repository.py index d1f36063..a7fedd44 100644 --- a/monasca_persister/tests/test_influxdb_metrics_repository.py +++ b/monasca_persister/tests/test_influxdb_metrics_repository.py @@ -13,14 +13,22 @@ # See the License for the specific language governing permissions and # limitations under the License. +import influxdb +from influxdb.exceptions import InfluxDBClientError + from mock import Mock from mock import patch +from mock import call + +from monasca_persister.repositories.influxdb.metrics_repository import MetricInfluxdbRepository from oslotest import base from oslo_config import cfg -from monasca_persister.repositories.influxdb.metrics_repository import MetricInfluxdbRepository +import six +db_not_found = InfluxDBClientError( + content='{"error": "database not found: db"}', code=404) class TestMetricInfluxdbRepository(base.BaseTestCase): @@ -30,13 +38,46 @@ class TestMetricInfluxdbRepository(base.BaseTestCase): def tearDown(self): super(TestMetricInfluxdbRepository, self).tearDown() - def test_process_message(self): - metric = self._get_metric() - with patch.object(cfg, 'CONF', return_value=None): - metric_repo = MetricInfluxdbRepository() - self.assertIsInstance(metric_repo.process_message(metric), tuple) + def _test_process_message(self, metrics_repo, data_points, metric, tenant): + _dp, _tenant = metrics_repo.process_message(metric) + self.assertIsInstance(_dp, six.string_types) + self.assertEqual(_tenant, tenant) + data_points.append(_tenant, _dp) - def _get_metric(self): + @patch.object(influxdb, 'InfluxDBClient') + @patch.object(cfg, 'CONF', return_value=None) + def _test_write_batch(self, mock_conf, mock_influxdb_client, + db_per_tenant, db_exists): + mock_conf.influxdb.database_name = db_name = 'db' + mock_conf.influxdb.db_per_tenant = db_per_tenant + t1 = u'fake_tenant_id_1' + t2 = u'fake_tenant_id_2' + m1 = self._get_metric(t1) + m2 = self._get_metric(t2) + metrics_repo = MetricInfluxdbRepository() + data_points = metrics_repo.data_points_class() + self._test_process_message(metrics_repo, data_points, m1, t1) + self._test_process_message(metrics_repo, data_points, m2, t2) + metrics_repo._influxdb_client = mock_influxdb_client + if db_exists: + metrics_repo._influxdb_client.write_points = Mock() + else: + metrics_repo._influxdb_client.write_points = Mock( + side_effect=[db_not_found, None, db_not_found, None]) + if db_per_tenant: + call1 = call('%s_%s' % (db_name, t1)) + call2 = call('%s_%s' % (db_name, t2)) + calls = [call1, call2] + else: + calls = [call(db_name)] + metrics_repo.write_batch(data_points) + if db_exists: + mock_influxdb_client.create_database.assert_not_called() + else: + mock_influxdb_client.create_database.assert_has_calls( + calls, any_order=True) + + def _get_metric(self, tenant_id): metric = ''' { "metric": @@ -54,7 +95,7 @@ class TestMetricInfluxdbRepository(base.BaseTestCase): "meta": { "region":"RegionOne", - "tenantId":"df4c002353de4399b92fa79d8374819b" + "tenantId":"''' + tenant_id + '''" }, "creation_time":1554725988 } @@ -62,3 +103,15 @@ class TestMetricInfluxdbRepository(base.BaseTestCase): message = Mock() message.value.return_value = metric return message + + def test_write_batch_db_exists(self): + self._test_write_batch(db_per_tenant=False, db_exists=True) + + def test_write_batch(self): + self._test_write_batch(db_per_tenant=False, db_exists=False) + + def test_write_batch_db_per_tenant_db_exists(self): + self._test_write_batch(db_per_tenant=True, db_exists=True) + + def test_write_batch_db_per_tenant(self): + self._test_write_batch(db_per_tenant=True, db_exists=False) diff --git a/releasenotes/notes/support-automatic-db-creation-0856216b42b91e7d.yaml b/releasenotes/notes/support-automatic-db-creation-0856216b42b91e7d.yaml new file mode 100644 index 00000000..c7796f42 --- /dev/null +++ b/releasenotes/notes/support-automatic-db-creation-0856216b42b91e7d.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Support for automatic database creation in InfluxDB has been added.