|
14 | 14 | #include "test_framework.h" |
15 | 15 | #include "test_helpers.h" |
16 | 16 | #include <cli/agent_profiles.h> |
| 17 | +#include <cli/activation_transaction.h> |
17 | 18 | #include <cli/cli.h> |
18 | 19 | #include <cli/progress_sink.h> |
19 | 20 | #include <daemon/bootstrap.h> |
@@ -646,6 +647,41 @@ TEST(cli_activation_refuses_when_cohort_does_not_drain) { |
646 | 647 | PASS(); |
647 | 648 | } |
648 | 649 |
|
| 650 | +/* Regression for #1416: when the activation transaction recorded a concrete |
| 651 | + * refusal (e.g. the Windows ACL safety check), the CLI must attribute the |
| 652 | + * failure to that check instead of blaming "active CBM sessions" - reporters |
| 653 | + * rebooted and hunted phantom handles because no sessions existed. The |
| 654 | + * sessions wording must remain for refusals with no recorded note. */ |
| 655 | +TEST(cli_activation_refusal_note_reaches_diagnostic_issue1416) { |
| 656 | + cbm_activation_transaction_note_refusal_for_testing( |
| 657 | + "acl-grants-cross-account-mutation to S-1-5-11", 0UL); |
| 658 | + cli_activation_fake_t fake = { |
| 659 | + .participants_active = true, |
| 660 | + .mutation_reserve_result = 0, |
| 661 | + }; |
| 662 | + cbm_cli_activation_ops_t ops = { |
| 663 | + .context = &fake, |
| 664 | + .reserve_for_mutation = cli_activation_fake_reserve_mutation, |
| 665 | + .mutation_lease_release = cli_activation_fake_release_mutation, |
| 666 | + .visible_diagnostic = cli_activation_fake_diagnostic, |
| 667 | + }; |
| 668 | + ASSERT_EQ(cbm_cli_activation_guard_with_ops(&ops, cli_activation_fake_mutation, &fake), 1); |
| 669 | + ASSERT_NOT_NULL(strstr(fake.diagnostic, "acl-grants-cross-account-mutation")); |
| 670 | + ASSERT_NOT_NULL(strstr(fake.diagnostic, "not a session problem")); |
| 671 | + ASSERT_NULL(strstr(fake.diagnostic, "could not be stopped safely")); |
| 672 | + |
| 673 | + /* No note recorded -> the sessions wording is still the right message. */ |
| 674 | + cbm_activation_transaction_note_refusal_for_testing(NULL, 0UL); |
| 675 | + cli_activation_fake_t plain = { |
| 676 | + .participants_active = true, |
| 677 | + .mutation_reserve_result = 0, |
| 678 | + }; |
| 679 | + ops.context = &plain; |
| 680 | + ASSERT_EQ(cbm_cli_activation_guard_with_ops(&ops, cli_activation_fake_mutation, &plain), 1); |
| 681 | + ASSERT_NOT_NULL(strstr(plain.diagnostic, "could not be stopped safely")); |
| 682 | + PASS(); |
| 683 | +} |
| 684 | + |
649 | 685 | TEST(cli_activation_refuses_unsafe_cohort_reservation) { |
650 | 686 | cli_activation_fake_t fake = { |
651 | 687 | .mutation_reserve_result = -1, |
@@ -11891,6 +11927,7 @@ SUITE(cli) { |
11891 | 11927 | /* Mandatory daemon activation safety */ |
11892 | 11928 | RUN_TEST(cli_activation_quiesces_active_cohort_before_mutation); |
11893 | 11929 | RUN_TEST(cli_activation_refuses_when_cohort_does_not_drain); |
| 11930 | + RUN_TEST(cli_activation_refusal_note_reaches_diagnostic_issue1416); |
11894 | 11931 | RUN_TEST(cli_activation_refuses_unsafe_cohort_reservation); |
11895 | 11932 | RUN_TEST(cli_activation_releases_maintenance_lease_after_success); |
11896 | 11933 | RUN_TEST(cli_activation_releases_maintenance_lease_when_mutation_fails); |
|
0 commit comments