github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/trust/revoke_test.go (about) 1 package trust 2 3 import ( 4 "context" 5 "io" 6 "testing" 7 8 "github.com/docker/cli/cli/trust" 9 "github.com/docker/cli/internal/test" 10 "github.com/docker/cli/internal/test/notary" 11 "github.com/theupdateframework/notary/client" 12 "github.com/theupdateframework/notary/passphrase" 13 "github.com/theupdateframework/notary/trustpinning" 14 "gotest.tools/v3/assert" 15 is "gotest.tools/v3/assert/cmp" 16 "gotest.tools/v3/golden" 17 ) 18 19 func TestTrustRevokeCommandErrors(t *testing.T) { 20 testCases := []struct { 21 name string 22 args []string 23 expectedError string 24 }{ 25 { 26 name: "not-enough-args", 27 expectedError: "requires exactly 1 argument", 28 }, 29 { 30 name: "too-many-args", 31 args: []string{"remote1", "remote2"}, 32 expectedError: "requires exactly 1 argument", 33 }, 34 { 35 name: "sha-reference", 36 args: []string{"870d292919d01a0af7e7f056271dc78792c05f55f49b9b9012b6d89725bd9abd"}, 37 expectedError: "invalid repository name", 38 }, 39 { 40 name: "invalid-img-reference", 41 args: []string{"ALPINE"}, 42 expectedError: "invalid reference format", 43 }, 44 { 45 name: "digest-reference", 46 args: []string{"ubuntu@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2"}, 47 expectedError: "cannot use a digest reference for IMAGE:TAG", 48 }, 49 } 50 for _, tc := range testCases { 51 cmd := newRevokeCommand( 52 test.NewFakeCli(&fakeClient{})) 53 cmd.SetArgs(tc.args) 54 cmd.SetOut(io.Discard) 55 assert.ErrorContains(t, cmd.Execute(), tc.expectedError) 56 } 57 } 58 59 func TestTrustRevokeCommand(t *testing.T) { 60 revokeCancelledError := "trust revoke has been cancelled" 61 62 testCases := []struct { 63 doc string 64 notaryRepository func(trust.ImageRefAndAuth, []string) (client.Repository, error) 65 args []string 66 expectedErr string 67 expectedMessage string 68 }{ 69 { 70 doc: "OfflineErrors_Confirm", 71 notaryRepository: notary.GetOfflineNotaryRepository, 72 args: []string{"reg-name.io/image"}, 73 expectedMessage: "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] ", 74 expectedErr: revokeCancelledError, 75 }, 76 { 77 doc: "OfflineErrors_Offline", 78 notaryRepository: notary.GetOfflineNotaryRepository, 79 args: []string{"reg-name.io/image", "-y"}, 80 expectedErr: "could not remove signature for reg-name.io/image: client is offline", 81 }, 82 { 83 doc: "OfflineErrors_WithTag_Offline", 84 notaryRepository: notary.GetOfflineNotaryRepository, 85 args: []string{"reg-name.io/image:tag"}, 86 expectedErr: "could not remove signature for reg-name.io/image:tag: client is offline", 87 }, 88 { 89 doc: "UninitializedErrors_Confirm", 90 notaryRepository: notary.GetUninitializedNotaryRepository, 91 args: []string{"reg-name.io/image"}, 92 expectedMessage: "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] ", 93 expectedErr: revokeCancelledError, 94 }, 95 { 96 doc: "UninitializedErrors_NoTrustData", 97 notaryRepository: notary.GetUninitializedNotaryRepository, 98 args: []string{"reg-name.io/image", "-y"}, 99 expectedErr: "could not remove signature for reg-name.io/image: does not have trust data for", 100 }, 101 { 102 doc: "UninitializedErrors_WithTag_NoTrustData", 103 notaryRepository: notary.GetUninitializedNotaryRepository, 104 args: []string{"reg-name.io/image:tag"}, 105 expectedErr: "could not remove signature for reg-name.io/image:tag: does not have trust data for", 106 }, 107 { 108 doc: "EmptyNotaryRepo_Confirm", 109 notaryRepository: notary.GetEmptyTargetsNotaryRepository, 110 args: []string{"reg-name.io/image"}, 111 expectedMessage: "Please confirm you would like to delete all signature data for reg-name.io/image? [y/N] ", 112 expectedErr: revokeCancelledError, 113 }, 114 { 115 doc: "EmptyNotaryRepo_NoSignedTags", 116 notaryRepository: notary.GetEmptyTargetsNotaryRepository, 117 args: []string{"reg-name.io/image", "-y"}, 118 expectedErr: "could not remove signature for reg-name.io/image: no signed tags to remove", 119 }, 120 { 121 doc: "EmptyNotaryRepo_NoValidTrustData", 122 notaryRepository: notary.GetEmptyTargetsNotaryRepository, 123 args: []string{"reg-name.io/image:tag"}, 124 expectedErr: "could not remove signature for reg-name.io/image:tag: No valid trust data for tag", 125 }, 126 { 127 doc: "AllSigConfirmation", 128 notaryRepository: notary.GetEmptyTargetsNotaryRepository, 129 args: []string{"alpine"}, 130 expectedMessage: "Please confirm you would like to delete all signature data for alpine? [y/N] ", 131 expectedErr: revokeCancelledError, 132 }, 133 } 134 135 for _, tc := range testCases { 136 t.Run(tc.doc, func(t *testing.T) { 137 cli := test.NewFakeCli(&fakeClient{}) 138 cli.SetNotaryClient(tc.notaryRepository) 139 cmd := newRevokeCommand(cli) 140 cmd.SetArgs(tc.args) 141 cmd.SetOut(io.Discard) 142 if tc.expectedErr != "" { 143 assert.ErrorContains(t, cmd.Execute(), tc.expectedErr) 144 } else { 145 assert.NilError(t, cmd.Execute()) 146 } 147 assert.Check(t, is.Contains(cli.OutBuffer().String(), tc.expectedMessage)) 148 }) 149 } 150 } 151 152 func TestGetSignableRolesForTargetAndRemoveError(t *testing.T) { 153 notaryRepo, err := client.NewFileCachedRepository(t.TempDir(), "gun", "https://localhost", nil, passphrase.ConstantRetriever("password"), trustpinning.TrustPinConfig{}) 154 assert.NilError(t, err) 155 target := client.Target{} 156 err = getSignableRolesForTargetAndRemove(target, notaryRepo) 157 assert.Error(t, err, "client is offline") 158 } 159 160 func TestRevokeTrustPromptTermination(t *testing.T) { 161 ctx, cancel := context.WithCancel(context.Background()) 162 t.Cleanup(cancel) 163 164 cli := test.NewFakeCli(&fakeClient{}) 165 cmd := newRevokeCommand(cli) 166 cmd.SetArgs([]string{"example/trust-demo"}) 167 test.TerminatePrompt(ctx, t, cmd, cli) 168 golden.Assert(t, cli.OutBuffer().String(), "trust-revoke-prompt-termination.golden") 169 }