-
Notifications
You must be signed in to change notification settings - Fork 54
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix the flaky alarms tests #1765
Fix the flaky alarms tests #1765
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good. I have some questions though.
@@ -1274,6 +1244,7 @@ fn extract_child_id(in_topic: &str, expected_child_id: Option<String>) { | |||
} | |||
|
|||
#[tokio::test] | |||
#[serial] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need to have all these tests serial?
They behave correctly even without serial when both c8y_mapper_alarm_empty_payload
and c8y_mapper_child_alarm_empty_payload
are ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, that's right. But, I observed that the test c8y-converter
needs the broker, to be on the safer side I made them run serially.
"tedge/alarms/major/temperature_alarm", | ||
"tedge/alarms/major/temperature_alarm/external_sensor", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this instance of tedge/alarms/major/temperature_alarm
is replaced by tedge/alarms/major/temperature_alarm/external_sensor
while the others (above) are replaced by tedge/alarms/major/custom_temperature_alarm"
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because there was a typo in the topic, the alarm that was sent on "tedge/alarms/major/temperature_alarm/external_sensor
had to be cleared sending an empty message on the same topic.
Signed-off-by: Pradeep Kumar K J <pradeepkumar.kj@softwareag.com>
while let Ok(Some(msg)) = messages.next().with_timeout(TEST_TIMEOUT_MS).await { | ||
assert_json_include!(actual:serde_json::from_str::<serde_json::Value>(&msg).unwrap(), expected:expected_msg); | ||
} | ||
let expected_msg = r#"{"severity":"MAJOR","type":"custom_temperature_alarm","time":"2023-01-25T18:41:14.776170774Z","text":"Temperature high","customFragment":{"nested":{"value":"extra info"}}}"#; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming that you converted this to raw string to use the assert_received_all_expected
function that expects string. You could have used the to_string()
function on the earlier json::Value
as well, right? So that you get a string without affecting the code readability. It doesn't matter in this specific case as the JSON was not formatted properly in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, thats right. I felt converting from json
to string is not necessary if a raw string is used directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using json!
is just for better readability, especially with multi-level JSON structs. More of a good to have feature than a must.
|
||
// Expect converted temperature alarm message | ||
mqtt_tests::assert_received_all_expected(&mut messages, TEST_TIMEOUT_MS, &[expected_msg]).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is still problematic as an assertion failure will prevent the cleanup logic below(clearing alarms) from executing. Not just in this test, but all alarm tests relying on this cleanup behaviour suffers from the same as you discovered yesterday.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I observed is that these tests run in serial and when the next test starts it will create a new broker instance, which will be a clean start and no persisted messages.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we don't even need that "alarm cleanup" step in all these tests, huh? Fine then. You can remove those cleanup steps if it's useless anyway. But, up-to you.
This PR has to be rebased to get the fix for test report generation. |
8ffdae7
to
0234c42
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got a question only.
r#"{ "text": "Temperature high","time":"2023-01-25T18:41:14.776170774Z","customFragment": {"nested":{"value": "extra info"}} }"#, | ||
mqtt_channel::QoS::AtLeastOnce, | ||
true, | ||
) | ||
.await | ||
.unwrap(); | ||
|
||
let expected_msg = json!({"severity":"MAJOR","type":"temperature_alarm","time":"2023-01-25T18:41:14.776170774Z","text":"Temperature high","customFragment":{"nested":{"value":"extra info"}}}); | ||
|
||
while let Ok(Some(msg)) = messages.next().with_timeout(TEST_TIMEOUT_MS).await { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the sporadically test failure is fixed by replacing this block by mqtt_tests::assert_received_all_expected
? It looks all other tests have this replacement.
I am just curious, because other locations than alarm also use this while let
block for testing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, using mqtt_tests::assert_received_all_expected
fixed the issue. Before I was trying to assert the json objects and was relying on the timeout
error when it does not receive. But, the call with_timeout
does not return an error, and because of this, the tests were always passing.
I did check at least two other places where while let
is being used, felt it's okay.
Robot Results
Passed Tests
|
while let Ok(Some(msg)) = messages.next().with_timeout(TEST_TIMEOUT_MS).await { | ||
assert_json_include!(actual:serde_json::from_str::<serde_json::Value>(&msg).unwrap(), expected:expected_msg); | ||
} | ||
let expected_msg = r#"{"severity":"MAJOR","type":"custom_temperature_alarm","time":"2023-01-25T18:41:14.776170774Z","text":"Temperature high","customFragment":{"nested":{"value":"extra info"}}}"#; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using json!
is just for better readability, especially with multi-level JSON structs. More of a good to have feature than a must.
|
||
// Expect converted temperature alarm message | ||
mqtt_tests::assert_received_all_expected(&mut messages, TEST_TIMEOUT_MS, &[expected_msg]).await; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, we don't even need that "alarm cleanup" step in all these tests, huh? Fine then. You can remove those cleanup steps if it's useless anyway. But, up-to you.
Proposed changes
This PR fixes the flaky alarm tests
serial
in the way the results validated
Types of changes
Paste Link to the issue
Checklist
cargo fmt
as mentioned in CODING_GUIDELINEScargo clippy
as mentioned in CODING_GUIDELINESFurther comments