import time import pytest from redfish_requests import Duration, RedfishHttpStatus def test_get_telemetry_service(redfish): r = redfish.get(redfish.telemetry_service_path) assert r["Status"]["State"] == "Enabled", "Invalid status of service" assert ( Duration.to_seconds(r["MinCollectionInterval"]) > 0 ), "Invalid duration format" assert r["MaxReports"] > 0, "Invalid count of max reports" def test_get_metric_definition_collection(redfish): r = redfish.get(redfish.metric_definition_path) assert "Members" in r, "Missing members property" assert "Members@odata.count" in r, "Missing members count property" def test_verify_metric_definition_members_if_contains_metrics(redfish): r = redfish.get(redfish.metric_definition_path) for m in r["Members"]: path = m["@odata.id"] metricDefinition = redfish.get(path) assert "MetricProperties" in metricDefinition, "Missing metrics" assert len(metricDefinition["MetricProperties"]) > 0, "Missing metrics" def test_get_metric_definition_that_not_exist_expect_not_found(redfish): redfish.get( f"{redfish.metric_definition_path}/NotExisting", code=RedfishHttpStatus.not_found, ) def test_get_metric_report_definition_collection(redfish): r = redfish.get(redfish.metric_report_definition_path) assert "Members" in r, "Missing members property" assert "Members@odata.count" in r, "Missing members count property" def test_get_metric_report_definition_that_not_exist_expect_not_found(redfish): redfish.get( f"{redfish.metric_report_definition_path}/NotExisting", code=RedfishHttpStatus.not_found, ) def test_get_metric_report_collection(redfish): r = redfish.get(redfish.metric_report_path) assert "Members" in r, "Missing members property" assert "Members@odata.count" in r, "Missing members count property" def test_get_metric_report_that_not_exist_expect_not_found(redfish): redfish.get( f"{redfish.metric_report_path}/NotExisting", code=RedfishHttpStatus.not_found, ) def test_post_report_definition_with_empty_body_expect_bad_request(redfish): redfish.post( redfish.metric_report_definition_path, body={}, code=RedfishHttpStatus.bad_request, ) def test_post_report_definition_with_some_body_expect_bad_request(redfish): redfish.post( redfish.metric_report_definition_path, body={"key": "value"}, code=RedfishHttpStatus.bad_request, ) def test_delete_non_exisiting_metric_report_definition(redfish): redfish.delete( f"{redfish.metric_report_definition_path}/NonExisitingReport", code=RedfishHttpStatus.not_found, ) def test_add_report(redfish, report_definitions): id = "Test" report_definitions.add_report(id) assert 1 == len(report_definitions.get_collection()) r = redfish.get(f"{redfish.metric_report_definition_path}/{id}") assert r["Id"] == id, "Invalid Id, different then requested" r = redfish.get(f"{redfish.metric_report_path}/{id}") assert r["Id"] == id, "Invalid Id, different then requested" def test_add_report_above_max_report_expect_bad_request( telemetry, report_definitions ): id = "Test" for i in range(telemetry.max_reports): report_definitions.add_report(id + str(i)) assert telemetry.max_reports == len(report_definitions.get_collection()) report_definitions.add_report( id + str(telemetry.max_reports), metrics=[], interval=telemetry.min_interval, code=RedfishHttpStatus.bad_request, ) def test_add_report_long_name(report_definitions): report_definitions.add_report("Test" * 65) def test_add_report_twice_expect_bad_request(report_definitions): report_definitions.add_report("Test") report_definitions.add_report("Test", code=RedfishHttpStatus.bad_request) @pytest.mark.parametrize( "actions", [ [], ["RedfishEvent"], ["LogToMetricReportsCollection"], ["RedfishEvent", "LogToMetricReportsCollection"], ], ) def test_add_report_with_actions(actions, redfish, report_definitions): report_definitions.add_report("Test", actions=actions) r = redfish.get(f"{redfish.metric_report_definition_path}/Test") assert ( r["ReportActions"] == actions ), "Invalid actions, different then requested" @pytest.mark.parametrize( "invalid_actions", [ ["NonExisting"], ["RedfishEvent", "Partially"], ["LogToMetricNotThisOne"], ], ) def test_add_report_with_invalid_actions_expect_bad_request( invalid_actions, report_definitions ): report_definitions.add_report( "Test", actions=invalid_actions, code=RedfishHttpStatus.bad_request ) @pytest.mark.parametrize("invalid_id", ["test_-", "t t", "T.T", "T,t", "T:t"]) def test_add_report_with_invalid_id_expect_bad_request( invalid_id, report_definitions ): report_definitions.add_report( invalid_id, code=RedfishHttpStatus.bad_request ) def test_add_report_with_metric(redfish, telemetry, report_definitions): if len(telemetry.metrics) <= 0: pytest.skip("Redfish has no sensor available") metric = {"MetricId": "Id1", "MetricProperties": [telemetry.metrics[0]]} report_definitions.add_report("Test", metrics=[metric]) r = redfish.get(redfish.metric_report_definition_path + "/Test") assert len(r["Metrics"]) == 1, "Invalid Metrics, different then requested" assert ( r["Metrics"][0]["MetricId"] == metric["MetricId"] ), "Invalid MetricId, different then requested" assert ( r["Metrics"][0]["MetricProperties"] == metric["MetricProperties"] ), "Invalid MetricProperties, different then requested" def test_add_report_with_invalid_metric_expect_bad_request(report_definitions): metric = { "MetricId": "Id1", "MetricProperties": [ "/redfish/v1/Chassis/chassis/Sensors/NonExisting/Reading" ], } report_definitions.add_report( "Test", metrics=[metric], code=RedfishHttpStatus.bad_request ) def test_add_report_with_many_metrics(redfish, telemetry, report_definitions): if len(telemetry.metrics) <= 0: pytest.skip("Redfish has no sensor available") metrics = [] for i, prop in enumerate(telemetry.metrics): metrics.append({"MetricId": f"Id{str(i)}", "MetricProperties": [prop]}) report_definitions.add_report("Test", metrics=metrics) r = redfish.get(redfish.metric_report_definition_path + "/Test") assert len(r["Metrics"]) == len( telemetry.metrics ), "Invalid Metrics, different then requested" def test_add_report_on_request_with_metric_expect_updated_metric_report( redfish, telemetry, report_definitions ): if len(telemetry.metrics) <= 0: pytest.skip("Redfish has no sensor available") metric = {"MetricId": "Id1", "MetricProperties": [telemetry.metrics[0]]} report_definitions.add_report("Test", metrics=[metric], type="OnRequest") r = redfish.get(redfish.metric_report_path + "/Test") assert len(r["MetricValues"]) > 0, "Missing MetricValues" metric_value = r["MetricValues"][0] assert metric_value["MetricValue"], "Missing MetricValues" assert ( metric_value["MetricId"] == metric["MetricId"] ), "Different Id then set in request" assert ( metric_value["MetricProperty"] == metric["MetricProperties"][0] ), "Different MetricProperty then set in request" def test_add_report_periodic_with_metric_expect_updated_metric_report( redfish, telemetry, report_definitions ): if len(telemetry.metrics) <= 0: pytest.skip("Redfish has no sensor available") metric = {"MetricId": "Id1", "MetricProperties": [telemetry.metrics[0]]} report_definitions.add_report( "Test", metrics=[metric], type="Periodic", interval=Duration.to_iso8061(telemetry.min_interval), ) time.sleep(telemetry.min_interval + 1) r = redfish.get(redfish.metric_report_path + "/Test") assert len(r["MetricValues"]) > 0, "Missing MetricValues" metric_value = r["MetricValues"][0] assert metric_value["MetricValue"], "Missing MetricValues" assert ( metric_value["MetricId"] == metric["MetricId"] ), "Different Id then set in request" assert ( metric_value["MetricProperty"] == metric["MetricProperties"][0] ), "Different MetricProperty then set in request" @pytest.mark.parametrize("interval", [10, 60, 2400, 90000]) def test_add_report_check_if_duration_is_set( interval, redfish, telemetry, report_definitions ): if interval < telemetry.min_interval: pytest.skip("Interval is below minimal acceptable value, skipping") id = f"Test{str(interval)}" report_definitions.add_report( id, type="Periodic", interval=Duration.to_iso8061(interval) ) r = redfish.get(f"{redfish.metric_report_definition_path}/{id}") assert r["Schedule"]["RecurrenceInterval"], "Missing RecurrenceInterval" r_interval = Duration.to_seconds(r["Schedule"]["RecurrenceInterval"]) assert interval == r_interval, "Invalid interval, different then requested" @pytest.mark.parametrize( "invalid", ["50000", "P12ST", "PT12S12", "PPPPD222T222H222M222.222S"] ) def test_add_report_with_invalid_duration_response_bad_request( invalid, report_definitions ): r = report_definitions.add_report( "Test", type="Periodic", interval=invalid, code=RedfishHttpStatus.bad_request, ) assert r["error"]["@Message.ExtendedInfo"][ 0 ], "Wrong response, not an error" info = r["error"]["@Message.ExtendedInfo"][0] assert ( "RecurrenceInterval" in info["MessageArgs"] ), 'Wrong response, should contain "RecurrenceInterval"' def test_stress_add_reports_with_many_metrics_check_metric_reports( redfish, telemetry, report_definitions ): if len(telemetry.metrics) <= 0: pytest.skip("Redfish has no sensor available") metrics = [] for i, prop in enumerate(telemetry.metrics): metrics.append({"MetricId": f"Id{str(i)}", "MetricProperties": [prop]}) for i in range(telemetry.max_reports): report_definitions.add_report(f"Test{str(i)}", metrics=metrics) for i in range(telemetry.max_reports): r = redfish.get( f"{redfish.metric_report_definition_path}/Test{str(i)}" ) assert len(r["Metrics"]) == len( telemetry.metrics ), "Invalid Metrics, different then requested" for i in range(telemetry.max_reports): r = redfish.get(f"{redfish.metric_report_path}/Test{str(i)}") assert len(r["MetricValues"]) > 0, "Missing MetricValues"