compare complement test results to a baseline

One thing that might be neat in the future is noticing differing results
while the tests are still running, and modifying the log messages to
indicate them. I can imagine situations where you would want to abort
the test run immediately after seeing the first regression.
This commit is contained in:
Benjamin Lee 2024-06-21 16:33:51 -07:00
parent ab883ffa44
commit 8eab6eea20
No known key found for this signature in database
GPG key ID: FB9624E2885D55A4
4 changed files with 481 additions and 6 deletions

220
complement-baseline.tsv Normal file
View file

@ -0,0 +1,220 @@
test result
GLOBAL FAIL
TestACLs PASS
TestBannedUserCannotSendJoin FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/event_with_mismatched_state_key FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/invite_event FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/join_event FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/leave_event FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/non-state_membership_event FAIL
TestCannotSendKnockViaSendKnockInMSC3787Room/regular_event FAIL
TestCannotSendNonJoinViaSendJoinV1 FAIL
TestCannotSendNonJoinViaSendJoinV1/event_with_mismatched_state_key PASS
TestCannotSendNonJoinViaSendJoinV1/invite_event PASS
TestCannotSendNonJoinViaSendJoinV1/knock_event PASS
TestCannotSendNonJoinViaSendJoinV1/leave_event FAIL
TestCannotSendNonJoinViaSendJoinV1/non-state_membership_event PASS
TestCannotSendNonJoinViaSendJoinV1/regular_event FAIL
TestCannotSendNonJoinViaSendJoinV2 FAIL
TestCannotSendNonJoinViaSendJoinV2/event_with_mismatched_state_key PASS
TestCannotSendNonJoinViaSendJoinV2/invite_event PASS
TestCannotSendNonJoinViaSendJoinV2/knock_event PASS
TestCannotSendNonJoinViaSendJoinV2/leave_event FAIL
TestCannotSendNonJoinViaSendJoinV2/non-state_membership_event PASS
TestCannotSendNonJoinViaSendJoinV2/regular_event FAIL
TestCannotSendNonKnockViaSendKnock FAIL
TestCannotSendNonLeaveViaSendLeaveV1 FAIL
TestCannotSendNonLeaveViaSendLeaveV1/event_with_mismatched_state_key FAIL
TestCannotSendNonLeaveViaSendLeaveV1/invite_event FAIL
TestCannotSendNonLeaveViaSendLeaveV1/join_event FAIL
TestCannotSendNonLeaveViaSendLeaveV1/knock_event FAIL
TestCannotSendNonLeaveViaSendLeaveV1/non-state_membership_event FAIL
TestCannotSendNonLeaveViaSendLeaveV1/regular_event FAIL
TestCannotSendNonLeaveViaSendLeaveV2 FAIL
TestCannotSendNonLeaveViaSendLeaveV2/event_with_mismatched_state_key FAIL
TestCannotSendNonLeaveViaSendLeaveV2/invite_event FAIL
TestCannotSendNonLeaveViaSendLeaveV2/join_event FAIL
TestCannotSendNonLeaveViaSendLeaveV2/knock_event FAIL
TestCannotSendNonLeaveViaSendLeaveV2/non-state_membership_event FAIL
TestCannotSendNonLeaveViaSendLeaveV2/regular_event FAIL
TestClientSpacesSummary FAIL
TestClientSpacesSummary/max_depth FAIL
TestClientSpacesSummary/pagination FAIL
TestClientSpacesSummary/query_whole_graph FAIL
TestClientSpacesSummary/redact_link FAIL
TestClientSpacesSummary/suggested_only FAIL
TestClientSpacesSummaryJoinRules FAIL
TestContentMediaV1 PASS
TestDeviceListsUpdateOverFederation FAIL
TestDeviceListsUpdateOverFederation/good_connectivity FAIL
TestDeviceListsUpdateOverFederation/interrupted_connectivity FAIL
TestDeviceListsUpdateOverFederation/stopped_server FAIL
TestDeviceListsUpdateOverFederationOnRoomJoin FAIL
TestEventAuth FAIL
TestFederatedClientSpaces FAIL
TestFederationKeyUploadQuery FAIL
TestFederationKeyUploadQuery/Can_claim_remote_one_time_key_using_POST FAIL
TestFederationKeyUploadQuery/Can_query_remote_device_keys_using_POST FAIL
TestFederationRedactSendsWithoutEvent PASS
TestFederationRejectInvite FAIL
TestFederationRoomsInvite FAIL
TestFederationRoomsInvite/Parallel FAIL
TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation FAIL
TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation_for_empty_room PASS
TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation_several_times FAIL
TestFederationRoomsInvite/Parallel/Invited_user_has_'is_direct'_flag_in_prev_content_after_joining PASS
TestFederationRoomsInvite/Parallel/Remote_invited_user_can_see_room_metadata PASS
TestFederationThumbnail PASS
TestGetMissingEventsGapFilling FAIL
TestInboundCanReturnMissingEvents FAIL
TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_invited_visibility FAIL
TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_joined_visibility FAIL
TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_shared_visibility FAIL
TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_world_readable_visibility FAIL
TestInboundFederationKeys PASS
TestInboundFederationProfile PASS
TestInboundFederationProfile/Inbound_federation_can_query_profile_data PASS
TestInboundFederationProfile/Non-numeric_ports_in_server_names_are_rejected PASS
TestInboundFederationRejectsEventsWithRejectedAuthEvents FAIL
TestIsDirectFlagFederation PASS
TestIsDirectFlagLocal PASS
TestJoinFederatedRoomFailOver PASS
TestJoinFederatedRoomFromApplicationServiceBridgeUser FAIL
TestJoinFederatedRoomFromApplicationServiceBridgeUser/join_remote_federated_room_as_application_service_user FAIL
TestJoinFederatedRoomWithUnverifiableEvents PASS
TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_missing_signatures_shouldn't_block_room_join PASS
TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_bad_signatures_shouldn't_block_room_join PASS
TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_state_with_unverifiable_auth_events_shouldn't_block_room_join PASS
TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_unobtainable_keys_shouldn't_block_room_join PASS
TestJoinViaRoomIDAndServerName PASS
TestJumpToDateEndpoint FAIL
TestJumpToDateEndpoint/parallel FAIL
TestJumpToDateEndpoint/parallel/federation FAIL
TestJumpToDateEndpoint/parallel/federation/can_paginate_after_getting_remote_event_from_timestamp_to_event_endpoint FAIL
TestJumpToDateEndpoint/parallel/federation/looking_backwards,_should_be_able_to_find_event_that_was_sent_before_we_joined FAIL
TestJumpToDateEndpoint/parallel/federation/looking_forwards,_should_be_able_to_find_event_that_was_sent_before_we_joined FAIL
TestJumpToDateEndpoint/parallel/federation/when_looking_backwards_before_the_room_was_created,_should_be_able_to_find_event_that_was_imported FAIL
TestJumpToDateEndpoint/parallel/should_find_event_after_given_timestmap FAIL
TestJumpToDateEndpoint/parallel/should_find_event_before_given_timestmap FAIL
TestJumpToDateEndpoint/parallel/should_find_next_event_topologically_after_given_timestmap_when_all_message_timestamps_are_the_same FAIL
TestJumpToDateEndpoint/parallel/should_find_next_event_topologically_before_given_timestamp_when_all_message_timestamps_are_the_same FAIL
TestJumpToDateEndpoint/parallel/should_find_nothing_after_the_latest_timestmap PASS
TestJumpToDateEndpoint/parallel/should_find_nothing_before_the_earliest_timestmap PASS
TestJumpToDateEndpoint/parallel/should_not_be_able_to_query_a_private_room_you_are_not_a_member_of FAIL
TestJumpToDateEndpoint/parallel/should_not_be_able_to_query_a_public_room_you_are_not_a_member_of FAIL
TestKnockRoomsInPublicRoomsDirectory FAIL
TestKnockRoomsInPublicRoomsDirectoryInMSC3787Room FAIL
TestKnocking FAIL
TestKnockingInMSC3787Room FAIL
TestKnockingInMSC3787Room/A_user_can_knock_on_a_room_without_a_reason FAIL
TestKnockingInMSC3787Room/A_user_can_knock_on_a_room_without_a_reason#01 FAIL
TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_in FAIL
TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_in#01 FAIL
TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_invited_to FAIL
TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_invited_to#01 FAIL
TestKnockingInMSC3787Room/A_user_in_the_room_can_accept_a_knock PASS
TestKnockingInMSC3787Room/A_user_in_the_room_can_accept_a_knock#01 PASS
TestKnockingInMSC3787Room/A_user_in_the_room_can_reject_a_knock FAIL
TestKnockingInMSC3787Room/A_user_in_the_room_can_reject_a_knock#01 FAIL
TestKnockingInMSC3787Room/A_user_that_has_already_knocked_is_allowed_to_knock_again_on_the_same_room FAIL
TestKnockingInMSC3787Room/A_user_that_has_already_knocked_is_allowed_to_knock_again_on_the_same_room#01 FAIL
TestKnockingInMSC3787Room/A_user_that_has_knocked_on_a_local_room_can_rescind_their_knock_and_then_knock_again FAIL
TestKnockingInMSC3787Room/A_user_that_is_banned_from_a_room_cannot_knock_on_it FAIL
TestKnockingInMSC3787Room/A_user_that_is_banned_from_a_room_cannot_knock_on_it#01 FAIL
TestKnockingInMSC3787Room/Attempting_to_join_a_room_with_join_rule_'knock'_without_an_invite_should_fail FAIL
TestKnockingInMSC3787Room/Attempting_to_join_a_room_with_join_rule_'knock'_without_an_invite_should_fail#01 FAIL
TestKnockingInMSC3787Room/Change_the_join_rule_of_a_room_from_'invite'_to_'knock' PASS
TestKnockingInMSC3787Room/Change_the_join_rule_of_a_room_from_'invite'_to_'knock'#01 PASS
TestKnockingInMSC3787Room/Knocking_on_a_room_with_a_join_rule_other_than_'knock'_should_fail FAIL
TestKnockingInMSC3787Room/Knocking_on_a_room_with_a_join_rule_other_than_'knock'_should_fail#01 FAIL
TestKnockingInMSC3787Room/Knocking_on_a_room_with_join_rule_'knock'_should_succeed FAIL
TestKnockingInMSC3787Room/Knocking_on_a_room_with_join_rule_'knock'_should_succeed#01 FAIL
TestKnockingInMSC3787Room/Users_in_the_room_see_a_user's_membership_update_when_they_knock FAIL
TestKnockingInMSC3787Room/Users_in_the_room_see_a_user's_membership_update_when_they_knock#01 FAIL
TestLocalPngThumbnail PASS
TestLocalPngThumbnail/test_/_matrix/client/v1/media_endpoint PASS
TestMediaFilenames FAIL
TestMediaFilenames/Parallel FAIL
TestMediaFilenames/Parallel/ASCII FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'ascii' FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'ascii'_over_/_matrix/client/v1/media/download FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'name;with;semicolons' FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'name;with;semicolons'_over_/_matrix/client/v1/media/download FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'name_with_spaces' FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_file_'name_with_spaces'_over_/_matrix/client/v1/media/download FAIL
TestMediaFilenames/Parallel/ASCII/Can_download_specifying_a_different_ASCII_file_name PASS
TestMediaFilenames/Parallel/ASCII/Can_download_specifying_a_different_ASCII_file_name_over__matrix/client/v1/media/download PASS
TestMediaFilenames/Parallel/ASCII/Can_upload_with_ASCII_file_name PASS
TestMediaFilenames/Parallel/Unicode FAIL
TestMediaFilenames/Parallel/Unicode/Can_download_specifying_a_different_Unicode_file_name PASS
TestMediaFilenames/Parallel/Unicode/Can_download_specifying_a_different_Unicode_file_name_over__matrix/client/v1/media/download PASS
TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_locally FAIL
TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_locally_over__matrix/client/v1/media/download FAIL
TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_over_federation FAIL
TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_over_federation_via__matrix/client/v1/media/download FAIL
TestMediaFilenames/Parallel/Unicode/Can_upload_with_Unicode_file_name PASS
TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_as_inline SKIP
TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_as_inline_via__matrix/client/v1/media/download SKIP
TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_with_parameters_as_inline SKIP
TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_with_parameters_as_inline_via__matrix/client/v1/media/download SKIP
TestMediaFilenames/Parallel/Unicode/Will_serve_unsafe_media_types_as_attachments SKIP
TestMediaFilenames/Parallel/Unicode/Will_serve_unsafe_media_types_as_attachments_via__matrix/client/v1/media/download SKIP
TestMediaWithoutFileName FAIL
TestMediaWithoutFileName/parallel FAIL
TestMediaWithoutFileName/parallel/Can_download_without_a_file_name_locally PASS
TestMediaWithoutFileName/parallel/Can_download_without_a_file_name_over_federation FAIL
TestMediaWithoutFileName/parallel/Can_upload_without_a_file_name PASS
TestMediaWithoutFileNameCSMediaV1 PASS
TestMediaWithoutFileNameCSMediaV1/parallel PASS
TestMediaWithoutFileNameCSMediaV1/parallel/Can_download_without_a_file_name_locally PASS
TestMediaWithoutFileNameCSMediaV1/parallel/Can_download_without_a_file_name_over_federation PASS
TestMediaWithoutFileNameCSMediaV1/parallel/Can_upload_without_a_file_name PASS
TestNetworkPartitionOrdering FAIL
TestOutboundFederationIgnoresMissingEventWithBadJSONForRoomVersion6 FAIL
TestOutboundFederationProfile PASS
TestOutboundFederationProfile/Outbound_federation_can_query_profile_data PASS
TestOutboundFederationSend PASS
TestRemoteAliasRequestsUnderstandUnicode PASS
TestRemotePngThumbnail PASS
TestRemotePngThumbnail/test_/_matrix/client/v1/media_endpoint PASS
TestRemotePresence FAIL
TestRemotePresence/Presence_changes_are_also_reported_to_remote_room_members FAIL
TestRemotePresence/Presence_changes_to_UNAVAILABLE_are_reported_to_remote_room_members FAIL
TestRemoteTyping FAIL
TestRestrictedRoomsLocalJoin FAIL
TestRestrictedRoomsLocalJoinInMSC3787Room FAIL
TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_initially PASS
TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_when_left_allowed_room FAIL
TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_with_mangled_join_rules PASS
TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_succeed_when_invited FAIL
TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_succeed_when_joined_to_allowed_room PASS
TestRestrictedRoomsRemoteJoin FAIL
TestRestrictedRoomsRemoteJoinFailOver FAIL
TestRestrictedRoomsRemoteJoinFailOverInMSC3787Room FAIL
TestRestrictedRoomsRemoteJoinInMSC3787Room FAIL
TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_initially PASS
TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_when_left_allowed_room PASS
TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_with_mangled_join_rules PASS
TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_succeed_when_invited PASS
TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_succeed_when_joined_to_allowed_room FAIL
TestRestrictedRoomsRemoteJoinLocalUser FAIL
TestRestrictedRoomsRemoteJoinLocalUserInMSC3787Room FAIL
TestRestrictedRoomsSpacesSummaryFederation FAIL
TestRestrictedRoomsSpacesSummaryLocal FAIL
TestSendJoinPartialStateResponse SKIP
TestSyncOmitsStateChangeOnFilteredEvents PASS
TestToDeviceMessagesOverFederation FAIL
TestToDeviceMessagesOverFederation/good_connectivity PASS
TestToDeviceMessagesOverFederation/interrupted_connectivity FAIL
TestToDeviceMessagesOverFederation/stopped_server FAIL
TestUnbanViaInvite FAIL
TestUnknownEndpoints FAIL
TestUnknownEndpoints/Client-server_endpoints PASS
TestUnknownEndpoints/Key_endpoints FAIL
TestUnknownEndpoints/Media_endpoints PASS
TestUnknownEndpoints/Server-server_endpoints PASS
TestUnknownEndpoints/Unknown_prefix PASS
TestUnrejectRejectedEvents FAIL
TestUserAppearsInChangedDeviceListOnJoinOverFederation PASS
TestWriteMDirectAccountData PASS
1 test result
2 GLOBAL FAIL
3 TestACLs PASS
4 TestBannedUserCannotSendJoin FAIL
5 TestCannotSendKnockViaSendKnockInMSC3787Room FAIL
6 TestCannotSendKnockViaSendKnockInMSC3787Room/event_with_mismatched_state_key FAIL
7 TestCannotSendKnockViaSendKnockInMSC3787Room/invite_event FAIL
8 TestCannotSendKnockViaSendKnockInMSC3787Room/join_event FAIL
9 TestCannotSendKnockViaSendKnockInMSC3787Room/leave_event FAIL
10 TestCannotSendKnockViaSendKnockInMSC3787Room/non-state_membership_event FAIL
11 TestCannotSendKnockViaSendKnockInMSC3787Room/regular_event FAIL
12 TestCannotSendNonJoinViaSendJoinV1 FAIL
13 TestCannotSendNonJoinViaSendJoinV1/event_with_mismatched_state_key PASS
14 TestCannotSendNonJoinViaSendJoinV1/invite_event PASS
15 TestCannotSendNonJoinViaSendJoinV1/knock_event PASS
16 TestCannotSendNonJoinViaSendJoinV1/leave_event FAIL
17 TestCannotSendNonJoinViaSendJoinV1/non-state_membership_event PASS
18 TestCannotSendNonJoinViaSendJoinV1/regular_event FAIL
19 TestCannotSendNonJoinViaSendJoinV2 FAIL
20 TestCannotSendNonJoinViaSendJoinV2/event_with_mismatched_state_key PASS
21 TestCannotSendNonJoinViaSendJoinV2/invite_event PASS
22 TestCannotSendNonJoinViaSendJoinV2/knock_event PASS
23 TestCannotSendNonJoinViaSendJoinV2/leave_event FAIL
24 TestCannotSendNonJoinViaSendJoinV2/non-state_membership_event PASS
25 TestCannotSendNonJoinViaSendJoinV2/regular_event FAIL
26 TestCannotSendNonKnockViaSendKnock FAIL
27 TestCannotSendNonLeaveViaSendLeaveV1 FAIL
28 TestCannotSendNonLeaveViaSendLeaveV1/event_with_mismatched_state_key FAIL
29 TestCannotSendNonLeaveViaSendLeaveV1/invite_event FAIL
30 TestCannotSendNonLeaveViaSendLeaveV1/join_event FAIL
31 TestCannotSendNonLeaveViaSendLeaveV1/knock_event FAIL
32 TestCannotSendNonLeaveViaSendLeaveV1/non-state_membership_event FAIL
33 TestCannotSendNonLeaveViaSendLeaveV1/regular_event FAIL
34 TestCannotSendNonLeaveViaSendLeaveV2 FAIL
35 TestCannotSendNonLeaveViaSendLeaveV2/event_with_mismatched_state_key FAIL
36 TestCannotSendNonLeaveViaSendLeaveV2/invite_event FAIL
37 TestCannotSendNonLeaveViaSendLeaveV2/join_event FAIL
38 TestCannotSendNonLeaveViaSendLeaveV2/knock_event FAIL
39 TestCannotSendNonLeaveViaSendLeaveV2/non-state_membership_event FAIL
40 TestCannotSendNonLeaveViaSendLeaveV2/regular_event FAIL
41 TestClientSpacesSummary FAIL
42 TestClientSpacesSummary/max_depth FAIL
43 TestClientSpacesSummary/pagination FAIL
44 TestClientSpacesSummary/query_whole_graph FAIL
45 TestClientSpacesSummary/redact_link FAIL
46 TestClientSpacesSummary/suggested_only FAIL
47 TestClientSpacesSummaryJoinRules FAIL
48 TestContentMediaV1 PASS
49 TestDeviceListsUpdateOverFederation FAIL
50 TestDeviceListsUpdateOverFederation/good_connectivity FAIL
51 TestDeviceListsUpdateOverFederation/interrupted_connectivity FAIL
52 TestDeviceListsUpdateOverFederation/stopped_server FAIL
53 TestDeviceListsUpdateOverFederationOnRoomJoin FAIL
54 TestEventAuth FAIL
55 TestFederatedClientSpaces FAIL
56 TestFederationKeyUploadQuery FAIL
57 TestFederationKeyUploadQuery/Can_claim_remote_one_time_key_using_POST FAIL
58 TestFederationKeyUploadQuery/Can_query_remote_device_keys_using_POST FAIL
59 TestFederationRedactSendsWithoutEvent PASS
60 TestFederationRejectInvite FAIL
61 TestFederationRoomsInvite FAIL
62 TestFederationRoomsInvite/Parallel FAIL
63 TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation FAIL
64 TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation_for_empty_room PASS
65 TestFederationRoomsInvite/Parallel/Invited_user_can_reject_invite_over_federation_several_times FAIL
66 TestFederationRoomsInvite/Parallel/Invited_user_has_'is_direct'_flag_in_prev_content_after_joining PASS
67 TestFederationRoomsInvite/Parallel/Remote_invited_user_can_see_room_metadata PASS
68 TestFederationThumbnail PASS
69 TestGetMissingEventsGapFilling FAIL
70 TestInboundCanReturnMissingEvents FAIL
71 TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_invited_visibility FAIL
72 TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_joined_visibility FAIL
73 TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_shared_visibility FAIL
74 TestInboundCanReturnMissingEvents/Inbound_federation_can_return_missing_events_for_world_readable_visibility FAIL
75 TestInboundFederationKeys PASS
76 TestInboundFederationProfile PASS
77 TestInboundFederationProfile/Inbound_federation_can_query_profile_data PASS
78 TestInboundFederationProfile/Non-numeric_ports_in_server_names_are_rejected PASS
79 TestInboundFederationRejectsEventsWithRejectedAuthEvents FAIL
80 TestIsDirectFlagFederation PASS
81 TestIsDirectFlagLocal PASS
82 TestJoinFederatedRoomFailOver PASS
83 TestJoinFederatedRoomFromApplicationServiceBridgeUser FAIL
84 TestJoinFederatedRoomFromApplicationServiceBridgeUser/join_remote_federated_room_as_application_service_user FAIL
85 TestJoinFederatedRoomWithUnverifiableEvents PASS
86 TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_missing_signatures_shouldn't_block_room_join PASS
87 TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_bad_signatures_shouldn't_block_room_join PASS
88 TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_state_with_unverifiable_auth_events_shouldn't_block_room_join PASS
89 TestJoinFederatedRoomWithUnverifiableEvents//send_join_response_with_unobtainable_keys_shouldn't_block_room_join PASS
90 TestJoinViaRoomIDAndServerName PASS
91 TestJumpToDateEndpoint FAIL
92 TestJumpToDateEndpoint/parallel FAIL
93 TestJumpToDateEndpoint/parallel/federation FAIL
94 TestJumpToDateEndpoint/parallel/federation/can_paginate_after_getting_remote_event_from_timestamp_to_event_endpoint FAIL
95 TestJumpToDateEndpoint/parallel/federation/looking_backwards,_should_be_able_to_find_event_that_was_sent_before_we_joined FAIL
96 TestJumpToDateEndpoint/parallel/federation/looking_forwards,_should_be_able_to_find_event_that_was_sent_before_we_joined FAIL
97 TestJumpToDateEndpoint/parallel/federation/when_looking_backwards_before_the_room_was_created,_should_be_able_to_find_event_that_was_imported FAIL
98 TestJumpToDateEndpoint/parallel/should_find_event_after_given_timestmap FAIL
99 TestJumpToDateEndpoint/parallel/should_find_event_before_given_timestmap FAIL
100 TestJumpToDateEndpoint/parallel/should_find_next_event_topologically_after_given_timestmap_when_all_message_timestamps_are_the_same FAIL
101 TestJumpToDateEndpoint/parallel/should_find_next_event_topologically_before_given_timestamp_when_all_message_timestamps_are_the_same FAIL
102 TestJumpToDateEndpoint/parallel/should_find_nothing_after_the_latest_timestmap PASS
103 TestJumpToDateEndpoint/parallel/should_find_nothing_before_the_earliest_timestmap PASS
104 TestJumpToDateEndpoint/parallel/should_not_be_able_to_query_a_private_room_you_are_not_a_member_of FAIL
105 TestJumpToDateEndpoint/parallel/should_not_be_able_to_query_a_public_room_you_are_not_a_member_of FAIL
106 TestKnockRoomsInPublicRoomsDirectory FAIL
107 TestKnockRoomsInPublicRoomsDirectoryInMSC3787Room FAIL
108 TestKnocking FAIL
109 TestKnockingInMSC3787Room FAIL
110 TestKnockingInMSC3787Room/A_user_can_knock_on_a_room_without_a_reason FAIL
111 TestKnockingInMSC3787Room/A_user_can_knock_on_a_room_without_a_reason#01 FAIL
112 TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_in FAIL
113 TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_in#01 FAIL
114 TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_invited_to FAIL
115 TestKnockingInMSC3787Room/A_user_cannot_knock_on_a_room_they_are_already_invited_to#01 FAIL
116 TestKnockingInMSC3787Room/A_user_in_the_room_can_accept_a_knock PASS
117 TestKnockingInMSC3787Room/A_user_in_the_room_can_accept_a_knock#01 PASS
118 TestKnockingInMSC3787Room/A_user_in_the_room_can_reject_a_knock FAIL
119 TestKnockingInMSC3787Room/A_user_in_the_room_can_reject_a_knock#01 FAIL
120 TestKnockingInMSC3787Room/A_user_that_has_already_knocked_is_allowed_to_knock_again_on_the_same_room FAIL
121 TestKnockingInMSC3787Room/A_user_that_has_already_knocked_is_allowed_to_knock_again_on_the_same_room#01 FAIL
122 TestKnockingInMSC3787Room/A_user_that_has_knocked_on_a_local_room_can_rescind_their_knock_and_then_knock_again FAIL
123 TestKnockingInMSC3787Room/A_user_that_is_banned_from_a_room_cannot_knock_on_it FAIL
124 TestKnockingInMSC3787Room/A_user_that_is_banned_from_a_room_cannot_knock_on_it#01 FAIL
125 TestKnockingInMSC3787Room/Attempting_to_join_a_room_with_join_rule_'knock'_without_an_invite_should_fail FAIL
126 TestKnockingInMSC3787Room/Attempting_to_join_a_room_with_join_rule_'knock'_without_an_invite_should_fail#01 FAIL
127 TestKnockingInMSC3787Room/Change_the_join_rule_of_a_room_from_'invite'_to_'knock' PASS
128 TestKnockingInMSC3787Room/Change_the_join_rule_of_a_room_from_'invite'_to_'knock'#01 PASS
129 TestKnockingInMSC3787Room/Knocking_on_a_room_with_a_join_rule_other_than_'knock'_should_fail FAIL
130 TestKnockingInMSC3787Room/Knocking_on_a_room_with_a_join_rule_other_than_'knock'_should_fail#01 FAIL
131 TestKnockingInMSC3787Room/Knocking_on_a_room_with_join_rule_'knock'_should_succeed FAIL
132 TestKnockingInMSC3787Room/Knocking_on_a_room_with_join_rule_'knock'_should_succeed#01 FAIL
133 TestKnockingInMSC3787Room/Users_in_the_room_see_a_user's_membership_update_when_they_knock FAIL
134 TestKnockingInMSC3787Room/Users_in_the_room_see_a_user's_membership_update_when_they_knock#01 FAIL
135 TestLocalPngThumbnail PASS
136 TestLocalPngThumbnail/test_/_matrix/client/v1/media_endpoint PASS
137 TestMediaFilenames FAIL
138 TestMediaFilenames/Parallel FAIL
139 TestMediaFilenames/Parallel/ASCII FAIL
140 TestMediaFilenames/Parallel/ASCII/Can_download_file_'ascii' FAIL
141 TestMediaFilenames/Parallel/ASCII/Can_download_file_'ascii'_over_/_matrix/client/v1/media/download FAIL
142 TestMediaFilenames/Parallel/ASCII/Can_download_file_'name;with;semicolons' FAIL
143 TestMediaFilenames/Parallel/ASCII/Can_download_file_'name;with;semicolons'_over_/_matrix/client/v1/media/download FAIL
144 TestMediaFilenames/Parallel/ASCII/Can_download_file_'name_with_spaces' FAIL
145 TestMediaFilenames/Parallel/ASCII/Can_download_file_'name_with_spaces'_over_/_matrix/client/v1/media/download FAIL
146 TestMediaFilenames/Parallel/ASCII/Can_download_specifying_a_different_ASCII_file_name PASS
147 TestMediaFilenames/Parallel/ASCII/Can_download_specifying_a_different_ASCII_file_name_over__matrix/client/v1/media/download PASS
148 TestMediaFilenames/Parallel/ASCII/Can_upload_with_ASCII_file_name PASS
149 TestMediaFilenames/Parallel/Unicode FAIL
150 TestMediaFilenames/Parallel/Unicode/Can_download_specifying_a_different_Unicode_file_name PASS
151 TestMediaFilenames/Parallel/Unicode/Can_download_specifying_a_different_Unicode_file_name_over__matrix/client/v1/media/download PASS
152 TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_locally FAIL
153 TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_locally_over__matrix/client/v1/media/download FAIL
154 TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_over_federation FAIL
155 TestMediaFilenames/Parallel/Unicode/Can_download_with_Unicode_file_name_over_federation_via__matrix/client/v1/media/download FAIL
156 TestMediaFilenames/Parallel/Unicode/Can_upload_with_Unicode_file_name PASS
157 TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_as_inline SKIP
158 TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_as_inline_via__matrix/client/v1/media/download SKIP
159 TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_with_parameters_as_inline SKIP
160 TestMediaFilenames/Parallel/Unicode/Will_serve_safe_media_types_with_parameters_as_inline_via__matrix/client/v1/media/download SKIP
161 TestMediaFilenames/Parallel/Unicode/Will_serve_unsafe_media_types_as_attachments SKIP
162 TestMediaFilenames/Parallel/Unicode/Will_serve_unsafe_media_types_as_attachments_via__matrix/client/v1/media/download SKIP
163 TestMediaWithoutFileName FAIL
164 TestMediaWithoutFileName/parallel FAIL
165 TestMediaWithoutFileName/parallel/Can_download_without_a_file_name_locally PASS
166 TestMediaWithoutFileName/parallel/Can_download_without_a_file_name_over_federation FAIL
167 TestMediaWithoutFileName/parallel/Can_upload_without_a_file_name PASS
168 TestMediaWithoutFileNameCSMediaV1 PASS
169 TestMediaWithoutFileNameCSMediaV1/parallel PASS
170 TestMediaWithoutFileNameCSMediaV1/parallel/Can_download_without_a_file_name_locally PASS
171 TestMediaWithoutFileNameCSMediaV1/parallel/Can_download_without_a_file_name_over_federation PASS
172 TestMediaWithoutFileNameCSMediaV1/parallel/Can_upload_without_a_file_name PASS
173 TestNetworkPartitionOrdering FAIL
174 TestOutboundFederationIgnoresMissingEventWithBadJSONForRoomVersion6 FAIL
175 TestOutboundFederationProfile PASS
176 TestOutboundFederationProfile/Outbound_federation_can_query_profile_data PASS
177 TestOutboundFederationSend PASS
178 TestRemoteAliasRequestsUnderstandUnicode PASS
179 TestRemotePngThumbnail PASS
180 TestRemotePngThumbnail/test_/_matrix/client/v1/media_endpoint PASS
181 TestRemotePresence FAIL
182 TestRemotePresence/Presence_changes_are_also_reported_to_remote_room_members FAIL
183 TestRemotePresence/Presence_changes_to_UNAVAILABLE_are_reported_to_remote_room_members FAIL
184 TestRemoteTyping FAIL
185 TestRestrictedRoomsLocalJoin FAIL
186 TestRestrictedRoomsLocalJoinInMSC3787Room FAIL
187 TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_initially PASS
188 TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_when_left_allowed_room FAIL
189 TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_fail_with_mangled_join_rules PASS
190 TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_succeed_when_invited FAIL
191 TestRestrictedRoomsLocalJoinInMSC3787Room/Join_should_succeed_when_joined_to_allowed_room PASS
192 TestRestrictedRoomsRemoteJoin FAIL
193 TestRestrictedRoomsRemoteJoinFailOver FAIL
194 TestRestrictedRoomsRemoteJoinFailOverInMSC3787Room FAIL
195 TestRestrictedRoomsRemoteJoinInMSC3787Room FAIL
196 TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_initially PASS
197 TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_when_left_allowed_room PASS
198 TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_fail_with_mangled_join_rules PASS
199 TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_succeed_when_invited PASS
200 TestRestrictedRoomsRemoteJoinInMSC3787Room/Join_should_succeed_when_joined_to_allowed_room FAIL
201 TestRestrictedRoomsRemoteJoinLocalUser FAIL
202 TestRestrictedRoomsRemoteJoinLocalUserInMSC3787Room FAIL
203 TestRestrictedRoomsSpacesSummaryFederation FAIL
204 TestRestrictedRoomsSpacesSummaryLocal FAIL
205 TestSendJoinPartialStateResponse SKIP
206 TestSyncOmitsStateChangeOnFilteredEvents PASS
207 TestToDeviceMessagesOverFederation FAIL
208 TestToDeviceMessagesOverFederation/good_connectivity PASS
209 TestToDeviceMessagesOverFederation/interrupted_connectivity FAIL
210 TestToDeviceMessagesOverFederation/stopped_server FAIL
211 TestUnbanViaInvite FAIL
212 TestUnknownEndpoints FAIL
213 TestUnknownEndpoints/Client-server_endpoints PASS
214 TestUnknownEndpoints/Key_endpoints FAIL
215 TestUnknownEndpoints/Media_endpoints PASS
216 TestUnknownEndpoints/Server-server_endpoints PASS
217 TestUnknownEndpoints/Unknown_prefix PASS
218 TestUnrejectRejectedEvents FAIL
219 TestUserAppearsInChangedDeviceListOnJoinOverFederation PASS
220 TestWriteMDirectAccountData PASS

View file

@ -12,6 +12,7 @@ mod test2json;
use self::{ use self::{
docker::load_docker_image, docker::load_docker_image,
summary::{compare_summary, read_summary},
test2json::{count_complement_tests, run_complement}, test2json::{count_complement_tests, run_complement},
}; };
@ -23,6 +24,12 @@ pub(crate) struct Args {
/// If it exists and is not empty, an error will be returned. /// If it exists and is not empty, an error will be returned.
#[clap(short, long)] #[clap(short, long)]
out: PathBuf, out: PathBuf,
/// Baseline test summary file to compare with
///
/// If unspecified, defaults to `$repo_root/complement-baseline.tsv`
#[clap(short, long)]
baseline: Option<PathBuf>,
} }
#[allow(clippy::needless_pass_by_value)] #[allow(clippy::needless_pass_by_value)]
@ -30,6 +37,15 @@ pub(crate) fn main(args: Args) -> Result<()> {
let sh = Shell::new().unwrap(); let sh = Shell::new().unwrap();
let toplevel = get_toplevel_path(&sh) let toplevel = get_toplevel_path(&sh)
.wrap_err("failed to determine repository root directory")?; .wrap_err("failed to determine repository root directory")?;
let baseline_path = args
.baseline
.unwrap_or_else(|| toplevel.join("complement-baseline.tsv"));
let baseline = read_summary(&baseline_path).wrap_err_with(|| {
format!(
"failed to read baseline test result summary from \
{baseline_path:?}"
)
})?;
create_out_dir(&args.out).wrap_err_with(|| { create_out_dir(&args.out).wrap_err_with(|| {
format!("error initializing output directory {:?}", args.out) format!("error initializing output directory {:?}", args.out)
})?; })?;
@ -38,8 +54,11 @@ pub(crate) fn main(args: Args) -> Result<()> {
)?; )?;
let test_count = count_complement_tests(&sh, &docker_image) let test_count = count_complement_tests(&sh, &docker_image)
.wrap_err("failed to determine total complement test count")?; .wrap_err("failed to determine total complement test count")?;
run_complement(&sh, &args.out, &docker_image, test_count) let results = run_complement(&sh, &args.out, &docker_image, test_count)
.wrap_err("failed to run complement tests")?; .wrap_err("failed to run complement tests")?;
let summary_path = args.out.join("summary.tsv");
compare_summary(&baseline, &results, &baseline_path, &summary_path)?;
println!("\nTest results were identical to baseline.");
Ok(()) Ok(())
} }

View file

@ -6,10 +6,14 @@
use std::{ use std::{
collections::BTreeMap, collections::BTreeMap,
fs,
io::{BufWriter, Write}, io::{BufWriter, Write},
path::Path,
}; };
use miette::{IntoDiagnostic, Result}; use miette::{
miette, IntoDiagnostic, LabeledSpan, NamedSource, Result, WrapErr,
};
use super::test2json::TestResult; use super::test2json::TestResult;
@ -29,6 +33,30 @@ fn escape_tsv_value(value: &str) -> String {
.replace('\r', "\\r") .replace('\r', "\\r")
} }
/// Converts a string from a TSV value from to unescaped form.
fn unescape_tsv_value(value: &str) -> String {
let mut chars = value.chars();
let mut out = String::new();
while let Some(c) = chars.next() {
if c == '\\' {
match chars.next() {
Some('\\') => out.push('\\'),
Some('n') => out.push('\n'),
Some('t') => out.push('\t'),
Some('r') => out.push('\r'),
Some(c2) => {
out.push(c);
out.push(c2);
}
None => out.push(c),
}
} else {
out.push(c);
}
}
out
}
/// Write a test result summary to a writer. /// Write a test result summary to a writer.
pub(crate) fn write_summary<W: Write>( pub(crate) fn write_summary<W: Write>(
w: &mut BufWriter<W>, w: &mut BufWriter<W>,
@ -48,3 +76,211 @@ pub(crate) fn write_summary<W: Write>(
} }
Ok(()) Ok(())
} }
/// Reads test result summary from a TSV file written by a previous run of the
/// complement wrapper.
pub(crate) fn read_summary(
path: &Path,
) -> Result<BTreeMap<String, TestResult>> {
let contents = fs::read_to_string(path)
.into_diagnostic()
.wrap_err("failed to read summary file contents")?;
let source = NamedSource::new(path.to_string_lossy(), contents);
let contents = &source.inner();
let mut offset = 0;
// The TSV spec allows CRLF, but we never emit these ourselves
let mut lines = contents.split('\n');
let header_line = lines.next().ok_or_else(|| {
miette!(
labels = vec![LabeledSpan::at_offset(0, "expected header row")],
"summary file missing header row",
)
.with_source_code(source.clone())
})?;
let expected_header_line = "test\tresult";
if header_line != expected_header_line {
return Err(miette!(
labels = vec![LabeledSpan::at(
0..header_line.len(),
"unexpected header"
)],
"summary file header row has unexpected columns. Expecting \
{expected_header_line:?}."
)
.with_source_code(source));
}
offset += header_line.len() + 1;
let mut results = BTreeMap::new();
for line in lines {
if line.is_empty() {
continue;
}
let tabs = line.match_indices('\t').collect::<Vec<_>>();
let column_count = tabs.len() + 1;
let (result_span, test, result) = match tabs[..] {
[(first_tab, _)] => {
let result_span = offset + first_tab + 1..offset + line.len();
let test = line.get(..first_tab).expect(
"index should be valid because it was returned from \
'match_indices'",
);
let result = line.get(first_tab + 1..).expect(
"index should be valid because it was returned from \
'match_indices'",
);
(result_span, test, result)
}
[] => {
return Err(miette!(
labels = vec![LabeledSpan::at_offset(
offset + line.len(),
"expected more columns here"
)],
"each row in the summary file should have exactly two \
columns. This row only has {column_count} columns.",
)
.with_source_code(source))
}
[_, (first_bad_tab, _), ..] => {
let span = offset + first_bad_tab..offset + line.len();
return Err(miette!(
labels =
vec![LabeledSpan::at(span, "unexpected extra columns")],
"each row in the summary file should have exactly two \
columns. This row has {column_count} columns.",
)
.with_source_code(source));
}
};
let test = unescape_tsv_value(test);
let result = unescape_tsv_value(result);
let result = result.parse().map_err(|_| {
miette!(
labels =
vec![LabeledSpan::at(result_span, "invalid result value")],
"test result value must be one of 'PASS', 'FAIL', or 'SKIP'."
)
.with_source_code(source.clone())
})?;
results.insert(test, result);
offset += line.len() + 1;
}
Ok(results)
}
/// Print a bulleted list of test names, truncating if there are too many.
fn print_truncated_tests(tests: &[&str]) {
let max = 5;
for test in &tests[..max.min(tests.len())] {
println!(" - {test}");
}
if tests.len() > max {
println!(" ... ({} more)", tests.len() - max);
}
}
/// Compares new test results against older results, returning a error if they
/// differ.
///
/// A description of the differences will be logged separately from the returned
/// error.
pub(crate) fn compare_summary(
old: &TestResults,
new: &TestResults,
old_path: &Path,
new_path: &Path,
) -> Result<()> {
let mut unexpected_pass: Vec<&str> = Vec::new();
let mut unexpected_fail: Vec<&str> = Vec::new();
let mut unexpected_skip: Vec<&str> = Vec::new();
let mut added: Vec<&str> = Vec::new();
let mut removed: Vec<&str> = Vec::new();
for (test, new_result) in new {
if let Some(old_result) = old.get(test) {
if old_result != new_result {
match new_result {
TestResult::Pass => unexpected_pass.push(test),
TestResult::Fail => unexpected_fail.push(test),
TestResult::Skip => unexpected_skip.push(test),
}
}
} else {
added.push(test);
}
}
for test in old.keys() {
if !new.contains_key(test) {
removed.push(test);
}
}
let mut differences = false;
if !added.is_empty() {
differences = true;
println!(
"\n{} tests were added that were not present in the baseline:",
added.len()
);
print_truncated_tests(&added);
}
if !removed.is_empty() {
differences = true;
println!(
"\n{} tests present in the baseline were removed:",
removed.len()
);
print_truncated_tests(&removed);
}
if !unexpected_pass.is_empty() {
differences = true;
println!(
"\n{} tests passed that did not pass in the baseline:",
unexpected_pass.len()
);
print_truncated_tests(&unexpected_pass);
}
if !unexpected_skip.is_empty() {
differences = true;
println!(
"\n{} tests skipped that were not skipped in the baseline:",
unexpected_skip.len()
);
print_truncated_tests(&unexpected_skip);
}
if !unexpected_fail.is_empty() {
differences = true;
println!(
"\n{} tests failed that did not fail in the baseline (these are \
likely regressions):",
unexpected_fail.len()
);
print_truncated_tests(&unexpected_fail);
}
if differences {
Err(miette!(
help = format!(
"Evaluate each of the differences to determine whether they \
are expected. If all differences are expected, copy the new \
summary file {new_path:?} to {old_path:?} and commit the \
change. If some differences are unexpected, fix them and try \
another test run.\n\nAn example of an expected change would \
be a test that is now passing after your changes fixed it. \
An example of an unexpected change would be an unrelated \
test that is now failing, which would be a regression."
),
"Test results differed from baseline in {old_path:?}. The \
differences are described above."
))
} else {
Ok(())
}
}

View file

@ -14,7 +14,7 @@ use std::{
use indicatif::{ProgressBar, ProgressStyle}; use indicatif::{ProgressBar, ProgressStyle};
use miette::{miette, IntoDiagnostic, LabeledSpan, Result, WrapErr}; use miette::{miette, IntoDiagnostic, LabeledSpan, Result, WrapErr};
use serde::Deserialize; use serde::Deserialize;
use strum::Display; use strum::{Display, EnumString};
use xshell::{cmd, Shell}; use xshell::{cmd, Shell};
use super::summary::{write_summary, TestResults}; use super::summary::{write_summary, TestResults};
@ -43,7 +43,7 @@ pub(crate) fn run_complement(
out: &Path, out: &Path,
docker_image: &str, docker_image: &str,
test_count: u64, test_count: u64,
) -> Result<()> { ) -> Result<TestResults> {
// TODO: handle SIG{INT,TERM} // TODO: handle SIG{INT,TERM}
// TODO: XTASK_PATH variable, so that we don't need to pollute devshell with // TODO: XTASK_PATH variable, so that we don't need to pollute devshell with
// go // go
@ -70,7 +70,7 @@ pub(crate) fn run_complement(
ctx.handle_line(&line)?; ctx.handle_line(&line)?;
} }
Ok(()) Ok(ctx.results)
} }
/// Schema from <https://pkg.go.dev/cmd/test2json#hdr-Output_Format> /// Schema from <https://pkg.go.dev/cmd/test2json#hdr-Output_Format>
@ -103,7 +103,7 @@ enum GoTestEvent {
OtherAction, OtherAction,
} }
#[derive(Copy, Clone, Display, Debug)] #[derive(Copy, Clone, Display, EnumString, Eq, PartialEq, Debug)]
#[strum(serialize_all = "UPPERCASE")] #[strum(serialize_all = "UPPERCASE")]
pub(crate) enum TestResult { pub(crate) enum TestResult {
Pass, Pass,