[uss_qualifier/astm/utm] Validate operational intent changes are always published to DSS#1393
[uss_qualifier/astm/utm] Validate operational intent changes are always published to DSS#1393mickmis wants to merge 1 commit intointeruss:mainfrom
Conversation
…ys published to DSS
BenjaminPelletier
left a comment
There was a problem hiding this comment.
I suspect addressing these comments (particularly the cache key one) will resolve the CI issues.
| ) | ||
| from monitoring.monitorlib.transformations import Transformation | ||
|
|
||
| TIME_TOLERANCE = timedelta(seconds=1) |
There was a problem hiding this comment.
This is probably too lenient since we're just talking about numeric precision/representation errors
| TIME_TOLERANCE = timedelta(seconds=1) | |
| TIME_TOLERANCE = timedelta(milliseconds=10) |
| def append_err(name: str): | ||
| errors_text.append( | ||
| f"{name} reported by USS does not match the one published to the DSS" |
There was a problem hiding this comment.
It seems like it isn't that reported doesn't match DSS, it's that the details corresponding to a particular single version of an op intent are now reported differently than they previously were. So, I would expect a message more like (changing old_oi and new_oi types to OperationalIntent):
| def append_err(name: str): | |
| errors_text.append( | |
| f"{name} reported by USS does not match the one published to the DSS" | |
| def append_err(field_name: str): | |
| errors_text.append( | |
| f"The value {get_attr(new_oi.details, field_name)} for `{field_name}` reported by USS for details of operational intent {new_oi.reference.id} at version {new_oi.reference.version} (OVN {new_oi.reference.ovn if 'ovn' in new_oi.reference else 'empty'}) does not match the value {get_attr(old_oi.details, field_name)} previously indicated by the USS for the same operational intent with the same version" |
| return "; ".join(errors_text) if len(errors_text) > 0 else None | ||
|
|
||
|
|
||
| def validate_equivalent_op_intent_details( |
There was a problem hiding this comment.
nit: It seems like this would be clearer in communicating what this function will return:
| def validate_equivalent_op_intent_details( | |
| def errors_for_nonequivalent_op_intent_details( |
| [self._flight_planner.participant_id], | ||
| ) as check: | ||
| cache_key = ( | ||
| f"op_intent_details:{oi_full.reference.version}:{oi_full.reference.ovn}" |
There was a problem hiding this comment.
Seems like the ID is important here, but actually the OVN can't be because it's not ok to change the OVN for the same version. In fact, the OVN is one of the elements of the details that 1) can only be obtained from the USS and 2) shouldn't change. So, reference.ovn should actually be checked in validate_equivalent_op_intent_details.
The rest of the reference fields don't need to be checked there because a different check (#1378) ensures they match the DSS, and the DSS won't change those fields without synchronizing correctly.
| f"op_intent_details:{oi_full.reference.version}:{oi_full.reference.ovn}" | |
| f"op_intent_details:{oi_full.reference.id}:{oi_full.reference.version}" |
| cache_key = ( | ||
| f"op_intent_details:{oi_full.reference.version}:{oi_full.reference.ovn}" | ||
| ) | ||
| old_details = OperationalIntentDetails(self._scenario.cache.get(cache_key)) |
There was a problem hiding this comment.
I think we want to cache the full OperationalIntent (and probably query timestamp; see other comment).
I think the API unfortunately makes the language a little less clear than it could: in the text of the standard, the full information about the op intent is the "details" -- that is, "details" is inclusive of the information in the field reference. The API (somewhat confusingly) names the second field in OperationalIntent "details" rather than something more pedantically accurate like information_that_when_added_to_reference_forms_details. I've made a note to ASTM about perhaps making this more clear in the next version.
Caching the full OperationalIntent is the only way to directly detect if the USS has incorrectly changed ovn without informing the DSS since a client can't compare the ovn value reported by the DSS to the correct OVN in the DSS since the DSS won't provide the correct OVN to anyone other than the Entity's manager.
| If the operational intent details exposed by the USS have changed without the USS having updated the operational intent reference in the DSS, this check will fail per: | ||
| - **[astm.f3548.v21.USS0105,1](../../../requirements/astm/f3548/v21.md)** because the USS did not implement the operation _getOperationalIntentDetails_ correctly; and | ||
| - **[astm.f3548.v21.USS0005](../../../requirements/astm/f3548/v21.md)** because the USS did not make the operational intent correctly discoverable by the DSS. | ||
|
|
||
| Out of clarity, this check specifically targets cases where the USS changes details of the operational intent (volumes or priority) without a version or OVN change. |
There was a problem hiding this comment.
| If the operational intent details exposed by the USS have changed without the USS having updated the operational intent reference in the DSS, this check will fail per: | |
| - **[astm.f3548.v21.USS0105,1](../../../requirements/astm/f3548/v21.md)** because the USS did not implement the operation _getOperationalIntentDetails_ correctly; and | |
| - **[astm.f3548.v21.USS0005](../../../requirements/astm/f3548/v21.md)** because the USS did not make the operational intent correctly discoverable by the DSS. | |
| Out of clarity, this check specifically targets cases where the USS changes details of the operational intent (volumes or priority) without a version or OVN change. | |
| If the operational intent details reported by the USS have changed without the USS having updated the operational intent reference in the DSS, this check will fail because the USS did not make the changes to the operational intent discoverable using the DSS, per **[astm.f3548.v21.USS0005](../../../requirements/astm/f3548/v21.md)**. Per **[astm.f3548.v21.USS0105,1](../../../requirements/astm/f3548/v21.md)** (definition of `version` field), a USS must update the operational intent reference in the DSS, even when no data fields of the reference have changed, to make changes to the operational intent discoverable using the DSS. | |
| To be clear, this check specifically targets cases where the USS changes details of the operational intent without a version change. |
| check.record_failed( | ||
| summary="Operational intent details have changed without the change being published to the DSS", | ||
| details=error_text, | ||
| query_timestamps=[oi_full_query.request.timestamp], |
There was a problem hiding this comment.
It would be very useful to include the timestamp of the old query in addition to the new one. Fundamentally, we're saying we asked the USS for the same thing multiple times and they gave us different answers, so it would be super useful to quickly point a report reader to the multiple times we asked. Ideally, the combination of the test report and scenario documentation should be sufficient for most readers to be able to clearly and quickly identify the problem themselves. If we didn't include the "before" timestamp, I would expect a reader to ask how we know the details changed (how do we know the finding isn't a false positive?). With a timestamp, the answer to that is straightforward: "Look at your response A and your response B; they're different."
| # this function assumes all fields required by the OpenAPI definition are present as the format validation | ||
| # should have been performed by OpIntentValidator._evaluate_op_intent_validation before |
There was a problem hiding this comment.
I think no need to make this note, and it reduces reusability of the function.
The function's type annotations indicate that it should be provided valid OperationalIntentDetails, and all required fields have necessarily been validated in order for the provided value to actually be a valid OperationalIntentDetails. But, this function doesn't care where that validation is performed; when the function is reused, the validation might not happen where indicated here.
Closes #1379
This adds:
geo.pyandgeotemporal.pyaimed at implementing comparison with some tolerances