From ae9d5d78d10e51765eb371fbc30e82b13e49c3ce Mon Sep 17 00:00:00 2001 From: monokai <2536818783@qq.com> Date: Thu, 24 Jan 2019 17:41:57 +0800 Subject: [PATCH] Add metric report resource for RSD2.2 Change-Id: I4a67a9a1081f9c98e32fede1c52c6143f22e6db5 --- .../resources/v2_2/telemetry/metric_report.py | 102 ++++++++++ .../telemetry/metric_report_definition.py | 17 ++ rsd_lib/resources/v2_2/telemetry/telemetry.py | 17 ++ .../unit/json_samples/v2_2/metric_report.json | 37 ++++ .../v2_2/metric_report_collection.json | 12 ++ .../v2_2/telemetry/test_metric_report.py | 191 ++++++++++++++++++ .../test_metric_report_definition.py | 64 +++++- .../v2_2/telemetry/test_telemetry.py | 64 +++++- 8 files changed, 500 insertions(+), 4 deletions(-) create mode 100644 rsd_lib/resources/v2_2/telemetry/metric_report.py create mode 100644 rsd_lib/tests/unit/json_samples/v2_2/metric_report.json create mode 100644 rsd_lib/tests/unit/json_samples/v2_2/metric_report_collection.json create mode 100644 rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report.py diff --git a/rsd_lib/resources/v2_2/telemetry/metric_report.py b/rsd_lib/resources/v2_2/telemetry/metric_report.py new file mode 100644 index 0000000..19160d0 --- /dev/null +++ b/rsd_lib/resources/v2_2/telemetry/metric_report.py @@ -0,0 +1,102 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sushy.resources import base +from sushy import utils + +from rsd_lib import utils as rsd_lib_utils + + +class MetricValuesField(base.ListField): + metric_id = base.Field('MetricId') + """The value shall be the MetricId of the source metric within the + associated MetricDefinition + """ + + metric_value = base.Field('MetricValue') + """The value of the metric represented as a string. Its data type is + specified in including MetricResult.MetricDefinition. + """ + + time_stamp = base.Field('TimeStamp') + """The value shall be an ISO 8601 date time for when the metric value was + computed. Note that this may be different from the time when this + instance is created. If Volatile is true for a given metric value + instance, the TimeStamp changes whenever a new measurement snapshot + is taken. A management application may establish a time series of metric + data by retrieving the instances of metric value and sorting them + according to their TimeStamp. + """ + + metric_property = base.Field('MetricProperty') + """The value shall be a URI of a property contained in the scope of the + MetricScope + """ + + metric_definition = base.Field( + 'MetricDefinition', adapter=rsd_lib_utils.get_resource_identity) + """The value shall be a URI to the metric definition of the property""" + + +class MetricReport(base.ResourceBase): + identity = base.Field("Id") + """The metric report identity""" + + name = base.Field("Name") + """The metric report name""" + + description = base.Field("Description") + """The metric report description""" + + metric_values = MetricValuesField("MetricValues") + """The metric report definition""" + + def _get_metric_report_definition_path(self): + """Helper function to find the metric report definition path""" + return utils.get_sub_resource_path_by(self, 'MetricReportDefinition') + + @property + @utils.cache_it + def metric_report_definition(self): + """Property to provide reference to `MetricReportDefinition` + + It is calculated once the first time it is queried. On refresh, + this property is reset. + """ + # Avoid metric_report and metric_report_definition module mutually + # import each other, move import to this function + from rsd_lib.resources.v2_2.telemetry import metric_report_definition + return metric_report_definition.MetricReportDefinition( + self._conn, self._get_metric_report_definition_path(), + redfish_version=self.redfish_version) + + +class MetricReportCollection(base.ResourceCollectionBase): + + @property + def _resource_type(self): + return MetricReport + + def __init__(self, connector, path, redfish_version=None): + """A class representing a MetricReportCollection + + :param connector: A Connector instance + :param path: The canonical path to the Metric Report collection + resource + :param redfish_version: The version of RedFish. Used to construct + the object according to schema of the given version. + """ + super(MetricReportCollection, self).__init__(connector, path, + redfish_version) diff --git a/rsd_lib/resources/v2_2/telemetry/metric_report_definition.py b/rsd_lib/resources/v2_2/telemetry/metric_report_definition.py index d558d95..0ae65d3 100644 --- a/rsd_lib/resources/v2_2/telemetry/metric_report_definition.py +++ b/rsd_lib/resources/v2_2/telemetry/metric_report_definition.py @@ -21,6 +21,7 @@ from sushy.resources import base from sushy import utils from rsd_lib.resources.v2_2.telemetry import metric +from rsd_lib.resources.v2_2.telemetry import metric_report from rsd_lib.resources.v2_2.telemetry import metric_report_definition_schemas @@ -137,6 +138,22 @@ class MetricReportDefinition(base.ResourceBase): self._conn, path, redfish_version=self.redfish_version) for path in self._get_metrics_path()] + def _get_metric_report_path(self): + """Helper function to find the metric report path""" + return utils.get_sub_resource_path_by(self, 'MetricReport') + + @property + @utils.cache_it + def metric_report(self): + """Property to provide reference to `MetricReport` instance + + It is calculated once the first time it is queried. On refresh, + this property is reset. + """ + return metric_report.MetricReport( + self._conn, self._get_metric_report_path(), + redfish_version=self.redfish_version) + def delete(self): """Delete report definition""" self._conn.delete(self.path) diff --git a/rsd_lib/resources/v2_2/telemetry/telemetry.py b/rsd_lib/resources/v2_2/telemetry/telemetry.py index 4c8ddc4..5166715 100644 --- a/rsd_lib/resources/v2_2/telemetry/telemetry.py +++ b/rsd_lib/resources/v2_2/telemetry/telemetry.py @@ -17,6 +17,7 @@ from sushy.resources import base from sushy import utils from rsd_lib.resources.v2_2.telemetry import metric_definition +from rsd_lib.resources.v2_2.telemetry import metric_report from rsd_lib.resources.v2_2.telemetry import metric_report_definition from rsd_lib import utils as rsd_lib_utils @@ -78,3 +79,19 @@ class Telemetry(base.ResourceBase): return metric_report_definition.MetricReportDefinitionCollection( self._conn, self._get_metric_definitions_path(), redfish_version=self.redfish_version) + + def _get_metric_reports_path(self): + """Helper function to find the metric reports path""" + return utils.get_sub_resource_path_by(self, 'MetricReports') + + @property + @utils.cache_it + def metric_reports(self): + """Property to provide reference to `MetricReportCollection` + + It is calculated once the first time it is queried. On refresh, + this property is reset. + """ + return metric_report.MetricReportCollection( + self._conn, self._get_metric_reports_path(), + redfish_version=self.redfish_version) diff --git a/rsd_lib/tests/unit/json_samples/v2_2/metric_report.json b/rsd_lib/tests/unit/json_samples/v2_2/metric_report.json new file mode 100644 index 0000000..2cec4e6 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_2/metric_report.json @@ -0,0 +1,37 @@ +{ + "@odata.context":"/redfish/v1/$metadata#MetricReport.MetricReport", + "@odata.type":"#MetricReport.v1_0_0.MetricReport", + "@odata.id":"/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics", + "Id":"TransmitCPU1Metrics", + "Name":"CPU1 Metric Report", + "Description":"description-as-string", + "MetricReportDefinition":{ + "@odata.id":"/redfish/v1/TelemetryService/MetricReportDefinitions/CPU1Metrics" + }, + "MetricValues":[ + { + "MetricValue":"29", + "TimeStamp":"2016-07-25T11:27:59.895513984+02:00", + "MetricProperty":"/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/BandwidthPercent", + "MetricDefinition":{ + "@odata.id":"/redfish/v1/TelemetryService/MetricDefinitions/CPUBandwidth" + } + }, + { + "MetricValue":"FRB1 BIST Failure", + "TimeStamp":"2016-07-25T11:27:59.795513984+02:00", + "MetricProperty":"/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/CPUHealth", + "MetricDefinition":{ + "@odata.id":"/redfish/v1/TelemetryService/MetricDefinitions/CPUHealth" + } + }, + { + "MetricValue":"43", + "TimeStamp":"2016-07-25T11:27:59.595513984+02:00", + "MetricProperty":"/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/TemperatureCelsius", + "MetricDefinition":{ + "@odata.id":"/redfish/v1/TelemetryService/MetricDefinitions/CPUTemperature" + } + } + ] +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/json_samples/v2_2/metric_report_collection.json b/rsd_lib/tests/unit/json_samples/v2_2/metric_report_collection.json new file mode 100644 index 0000000..7d22c75 --- /dev/null +++ b/rsd_lib/tests/unit/json_samples/v2_2/metric_report_collection.json @@ -0,0 +1,12 @@ +{ + "@odata.context":"/redfish/v1/$metadata#TelemetryService/MetricReports", + "@odata.id":"/redfish/v1/TelemetryService/MetricReports", + "@odata.type":"#MetricReportCollection.MetricReportCollection", + "Name":"MetricReports", + "Members@odata.count":1, + "Members":[ + { + "@odata.id":"/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics" + } + ] +} \ No newline at end of file diff --git a/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report.py b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report.py new file mode 100644 index 0000000..a32e5b8 --- /dev/null +++ b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report.py @@ -0,0 +1,191 @@ +# Copyright 2019 Intel, Inc. +# All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import json +import mock +import testtools + +from sushy import exceptions + +from rsd_lib.resources.v2_2.telemetry import metric_report +from rsd_lib.resources.v2_2.telemetry import metric_report_definition + + +class MetricReportTestCase(testtools.TestCase): + + def setUp(self): + super(MetricReportTestCase, self).setUp() + self.conn = mock.Mock() + with open( + 'rsd_lib/tests/unit/json_samples/v2_2/metric_report.json', + 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.metric_report_inst = metric_report.MetricReport( + self.conn, + '/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics', + redfish_version='1.1.0') + + def test__parse_attributes(self): + self.metric_report_inst._parse_attributes() + self.assertEqual("TransmitCPU1Metrics", + self.metric_report_inst.identity) + self.assertEqual("CPU1 Metric Report", self.metric_report_inst.name) + self.assertEqual("description-as-string", + self.metric_report_inst.description) + # metric_values section + self.assertEqual( + None, self.metric_report_inst.metric_values[0].metric_id) + self.assertEqual( + "29", self.metric_report_inst.metric_values[0].metric_value) + self.assertEqual( + "2016-07-25T11:27:59.895513984+02:00", + self.metric_report_inst.metric_values[0].time_stamp) + self.assertEqual( + "/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/" + "BandwidthPercent", + self.metric_report_inst.metric_values[0].metric_property) + self.assertEqual( + "/redfish/v1/TelemetryService/MetricDefinitions/CPUBandwidth", + self.metric_report_inst.metric_values[0].metric_definition) + + self.assertEqual( + None, self.metric_report_inst.metric_values[1].metric_id) + self.assertEqual( + "FRB1 BIST Failure", + self.metric_report_inst.metric_values[1].metric_value) + self.assertEqual( + "2016-07-25T11:27:59.795513984+02:00", + self.metric_report_inst.metric_values[1].time_stamp) + self.assertEqual( + "/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/CPUHealth", + self.metric_report_inst.metric_values[1].metric_property) + self.assertEqual( + "/redfish/v1/TelemetryService/MetricDefinitions/CPUHealth", + self.metric_report_inst.metric_values[1].metric_definition) + + self.assertEqual( + None, self.metric_report_inst.metric_values[2].metric_id) + self.assertEqual( + "43", self.metric_report_inst.metric_values[2].metric_value) + self.assertEqual( + "2016-07-25T11:27:59.595513984+02:00", + self.metric_report_inst.metric_values[2].time_stamp) + self.assertEqual( + "/redfish/v1/Systems/System1/Processors/CPU1/Metrics#/" + "TemperatureCelsius", + self.metric_report_inst.metric_values[2].metric_property) + self.assertEqual( + "/redfish/v1/TelemetryService/MetricDefinitions/CPUTemperature", + self.metric_report_inst.metric_values[2].metric_definition) + + def test__get_metric_report_definition_path_path(self): + self.assertEqual( + '/redfish/v1/TelemetryService/MetricReportDefinitions/CPU1Metrics', + self.metric_report_inst._get_metric_report_definition_path()) + + def test__get_metric_report_definition_path_missing_systems_attr(self): + self.metric_report_inst._json.pop('MetricReportDefinition') + with self.assertRaisesRegex( + exceptions.MissingAttributeError, + 'attribute MetricReportDefinition'): + self.metric_report_inst._get_metric_report_definition_path() + + def test_metric_report_definition(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_definition.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_report_definition = \ + self.metric_report_inst.metric_report_definition + # | THEN | + self.assertIsInstance( + actual_report_definition, + metric_report_definition.MetricReportDefinition) + self.conn.get.return_value.json.assert_called_once_with() + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_report_definition, + self.metric_report_inst.metric_report_definition) + self.conn.get.return_value.json.assert_not_called() + + def test_metric_report_definitions_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_definition.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.metric_report_inst.metric_report_definition, + metric_report_definition.MetricReportDefinition) + + # On refreshing the telemetry service instance... + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.metric_report_inst.invalidate() + self.metric_report_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_definition.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.metric_report_inst.metric_report_definition, + metric_report_definition.MetricReportDefinition) + + +class MetricReportCollectionTestCase(testtools.TestCase): + + def setUp(self): + super(MetricReportCollectionTestCase, self).setUp() + self.conn = mock.Mock() + + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.metric_report_col = metric_report. MetricReportCollection( + self.conn, '/redfish/v1/TelemetryService/MetricReports', + redfish_version='1.1.0') + + def test_parse_attributes(self): + self.metric_report_col._parse_attributes() + self.assertEqual("MetricReports", self.metric_report_col.name) + + @mock.patch.object(metric_report, 'MetricReport', autospec=True) + def test_get_member(self, mock_metric_report): + self.metric_report_col.get_member( + '/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics') + + mock_metric_report.assert_called_once_with( + self.metric_report_col._conn, + '/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics', + redfish_version=self.metric_report_col.redfish_version + ) + + @mock.patch.object(metric_report, 'MetricReport', autospec=True) + def test_get_members(self, mock_metric_report): + members = self.metric_report_col.get_members() + self.assertEqual(mock_metric_report.call_count, 1) + self.assertIsInstance(members, list) + self.assertEqual(1, len(members)) diff --git a/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report_definition.py b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report_definition.py index cac77af..835cfd4 100644 --- a/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report_definition.py +++ b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_metric_report_definition.py @@ -21,6 +21,7 @@ import testtools from sushy import exceptions from rsd_lib.resources.v2_2.telemetry import metric +from rsd_lib.resources.v2_2.telemetry import metric_report from rsd_lib.resources.v2_2.telemetry import metric_report_definition from rsd_lib.tests.unit.fakes import request_fakes @@ -140,6 +141,65 @@ class ReportDefinitionTestCase(testtools.TestCase): self.assertIsInstance( self.metric_report_definition_inst.metrics[0], metric.Metric) + def test__get_metric_report_path_path(self): + self.assertEqual( + '/redfish/v1/TelemetryService/MetricReports/TransmitCPU1Metrics', + self.metric_report_definition_inst._get_metric_report_path()) + + def test__get_metric_report_path_missing_systems_attr(self): + self.metric_report_definition_inst._json.pop('MetricReport') + with self.assertRaisesRegex(exceptions.MissingAttributeError, + 'attribute MetricReport'): + self.metric_report_definition_inst._get_metric_report_path() + + def test_metric_report(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_metric_report = self.metric_report_definition_inst.metric_report + # | THEN | + self.assertIsInstance( + actual_metric_report, metric_report.MetricReport) + self.conn.get.return_value.json.assert_called_once_with() + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_metric_report, + self.metric_report_definition_inst.metric_report) + self.conn.get.return_value.json.assert_not_called() + + def test_metric_report_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.metric_report_definition_inst.metric_report, + metric_report.MetricReport) + + # On refreshing the telemetry service instance... + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'telemetry_service.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.metric_report_definition_inst.invalidate() + self.metric_report_definition_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.metric_report_definition_inst.metric_report, + metric_report.MetricReport) + def test_delete(self): self.metric_report_definition_inst.delete() self.metric_report_definition_inst._conn.delete.assert_called_once() @@ -168,8 +228,8 @@ class ReportDefinitionCollectionTestCase(testtools.TestCase): def test_parse_attributes(self): self.report_definition_col._parse_attributes() - self.assertEqual("MetricReportDefinition Collection", self. - report_definition_col.name) + self.assertEqual("MetricReportDefinition Collection", + self.report_definition_col.name) @mock.patch.object( metric_report_definition, 'MetricReportDefinition', autospec=True) diff --git a/rsd_lib/tests/unit/resources/v2_2/telemetry/test_telemetry.py b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_telemetry.py index 171d03c..612ab03 100644 --- a/rsd_lib/tests/unit/resources/v2_2/telemetry/test_telemetry.py +++ b/rsd_lib/tests/unit/resources/v2_2/telemetry/test_telemetry.py @@ -20,6 +20,7 @@ import testtools from sushy import exceptions from rsd_lib.resources.v2_2.telemetry import metric_definition +from rsd_lib.resources.v2_2.telemetry import metric_report from rsd_lib.resources.v2_2.telemetry import metric_report_definition from rsd_lib.resources.v2_2.telemetry import telemetry @@ -79,7 +80,7 @@ class TelemetryTestCase(testtools.TestCase): self.telemetry_inst.metric_definitions) self.conn.get.return_value.json.assert_not_called() - def test_metrics_definitions_on_refresh(self): + def test_metric_definitions_on_refresh(self): # | GIVEN | with open('rsd_lib/tests/unit/json_samples/v2_2/' 'metric_definition_collection.json', 'r') as f: @@ -139,7 +140,7 @@ class TelemetryTestCase(testtools.TestCase): self.telemetry_inst.metric_report_definitions) self.conn.get.return_value.json.assert_not_called() - def test_metrics_report_definitions_on_refresh(self): + def test_metric_report_definitions_on_refresh(self): # | GIVEN | with open('rsd_lib/tests/unit/json_samples/v2_2/' 'metric_report_definition_collection.json', 'r') as f: @@ -165,3 +166,62 @@ class TelemetryTestCase(testtools.TestCase): self.assertIsInstance( self.telemetry_inst.metric_report_definitions, metric_report_definition.MetricReportDefinitionCollection) + + def test__get_metric_reports_path_path(self): + self.assertEqual( + '/redfish/v1/TelemetryService/MetricReports', + self.telemetry_inst._get_metric_reports_path()) + + def test__get_metric_reports_path_missing_systems_attr(self): + self.telemetry_inst._json.pop('MetricReports') + with self.assertRaisesRegex(exceptions.MissingAttributeError, + 'attribute MetricReports'): + self.telemetry_inst._get_metric_reports_path() + + def test_metric_reports(self): + # | GIVEN | + self.conn.get.return_value.json.reset_mock() + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN | + actual_metric_reports = self.telemetry_inst.metric_reports + # | THEN | + self.assertIsInstance( + actual_metric_reports, metric_report.MetricReportCollection) + self.conn.get.return_value.json.assert_called_once_with() + + # reset mock + self.conn.get.return_value.json.reset_mock() + # | WHEN & THEN | + # tests for same object on invoking subsequently + self.assertIs(actual_metric_reports, + self.telemetry_inst.metric_reports) + self.conn.get.return_value.json.assert_not_called() + + def test_metric_reports_on_refresh(self): + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.telemetry_inst.metric_reports, + metric_report.MetricReportCollection) + + # On refreshing the telemetry service instance... + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'telemetry_service.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + + self.telemetry_inst.invalidate() + self.telemetry_inst.refresh(force=False) + + # | GIVEN | + with open('rsd_lib/tests/unit/json_samples/v2_2/' + 'metric_report_collection.json', 'r') as f: + self.conn.get.return_value.json.return_value = json.loads(f.read()) + # | WHEN & THEN | + self.assertIsInstance( + self.telemetry_inst.metric_reports, + metric_report.MetricReportCollection)