github.com/letsencrypt/boulder@v0.20251208.0/cmd/admin/unpause_account_test.go (about) 1 package main 2 3 import ( 4 "context" 5 "errors" 6 "os" 7 "path" 8 "strings" 9 "testing" 10 11 blog "github.com/letsencrypt/boulder/log" 12 sapb "github.com/letsencrypt/boulder/sa/proto" 13 "github.com/letsencrypt/boulder/test" 14 "google.golang.org/grpc" 15 ) 16 17 func TestReadingUnpauseAccountsFile(t *testing.T) { 18 t.Parallel() 19 20 testCases := []struct { 21 name string 22 data []string 23 expectedRegIDs int 24 }{ 25 { 26 name: "No data in file", 27 data: nil, 28 }, 29 { 30 name: "valid", 31 data: []string{"1"}, 32 expectedRegIDs: 1, 33 }, 34 { 35 name: "valid with duplicates", 36 data: []string{"1", "2", "1", "3", "3"}, 37 expectedRegIDs: 5, 38 }, 39 { 40 name: "valid with empty lines and duplicates", 41 data: []string{"1", "\n", "6", "6", "6"}, 42 expectedRegIDs: 4, 43 }, 44 } 45 46 for _, testCase := range testCases { 47 t.Run(testCase.name, func(t *testing.T) { 48 t.Parallel() 49 log := blog.NewMock() 50 a := admin{log: log} 51 52 file := path.Join(t.TempDir(), path.Base(t.Name()+".txt")) 53 err := os.WriteFile(file, []byte(strings.Join(testCase.data, "\n")), os.ModePerm) 54 test.AssertNotError(t, err, "could not write temporary file") 55 56 regIDs, err := a.readUnpauseAccountFile(file) 57 test.AssertNotError(t, err, "no error expected, but received one") 58 test.AssertEquals(t, len(regIDs), testCase.expectedRegIDs) 59 }) 60 } 61 } 62 63 type mockSAUnpause struct { 64 sapb.StorageAuthorityClient 65 } 66 67 func (msa *mockSAUnpause) UnpauseAccount(ctx context.Context, in *sapb.RegistrationID, _ ...grpc.CallOption) (*sapb.Count, error) { 68 return &sapb.Count{Count: 1}, nil 69 } 70 71 // mockSAUnpauseBroken is a mock that always returns an error. 72 type mockSAUnpauseBroken struct { 73 sapb.StorageAuthorityClient 74 } 75 76 func (msa *mockSAUnpauseBroken) UnpauseAccount(ctx context.Context, in *sapb.RegistrationID, _ ...grpc.CallOption) (*sapb.Count, error) { 77 return nil, errors.New("oh dear") 78 } 79 80 func TestUnpauseAccounts(t *testing.T) { 81 t.Parallel() 82 83 testCases := []struct { 84 name string 85 regIDs []int64 86 saImpl sapb.StorageAuthorityClient 87 expectErr bool 88 expectCounts int 89 }{ 90 { 91 name: "no data", 92 regIDs: nil, 93 expectErr: true, 94 }, 95 { 96 name: "valid single entry", 97 regIDs: []int64{1}, 98 expectCounts: 1, 99 }, 100 { 101 name: "valid single entry but broken SA", 102 expectErr: true, 103 saImpl: &mockSAUnpauseBroken{}, 104 regIDs: []int64{1}, 105 }, 106 { 107 name: "valid multiple entries with duplicates", 108 regIDs: []int64{1, 1, 2, 3, 4}, 109 expectCounts: 4, 110 }, 111 } 112 113 for _, testCase := range testCases { 114 t.Run(testCase.name, func(t *testing.T) { 115 t.Parallel() 116 117 log := blog.NewMock() 118 119 // Default to a working mock SA implementation 120 if testCase.saImpl == nil { 121 testCase.saImpl = &mockSAUnpause{} 122 } 123 a := admin{sac: testCase.saImpl, log: log} 124 125 counts, err := a.unpauseAccounts(context.Background(), testCase.regIDs, 10) 126 if testCase.expectErr { 127 test.AssertError(t, err, "should have errored, but did not") 128 } else { 129 test.AssertNotError(t, err, "should not have errored") 130 test.AssertEquals(t, testCase.expectCounts, len(counts)) 131 } 132 }) 133 } 134 }