github.com/opentofu/opentofu@v1.7.1/internal/encryption/registry/compliancetest/compliance_method.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package compliancetest 7 8 import ( 9 "errors" 10 "fmt" 11 "testing" 12 13 "github.com/opentofu/opentofu/internal/encryption/method" 14 "github.com/opentofu/opentofu/internal/encryption/registry" 15 ) 16 17 func complianceTestMethods(t *testing.T, factory func() registry.Registry) { 18 t.Run("registration-and-return", func(t *testing.T) { 19 complianceTestMethodRegistrationAndReturn(t, factory) 20 }) 21 t.Run("register-invalid-id", func(t *testing.T) { 22 complianceTestMethodInvalidID(t, factory) 23 }) 24 t.Run("duplicate-registration", func(t *testing.T) { 25 complianceTestMethodDuplicateRegistration(t, factory) 26 }) 27 } 28 29 func complianceTestMethodRegistrationAndReturn(t *testing.T, factory func() registry.Registry) { 30 reg := factory() 31 testMethod := &testMethodDescriptor{ 32 "test", 33 } 34 if err := reg.RegisterMethod(testMethod); err != nil { 35 t.Fatalf("Failed to register test method with ID %s (%v)", testMethod.id, err) 36 } 37 returnedMethod, err := reg.GetMethodDescriptor(testMethod.id) 38 if err != nil { 39 t.Fatalf("The previously registered method with the ID %s couldn't be fetched from the registry (%v).", testMethod.id, err) 40 } 41 returnedTypedMethod, ok := returnedMethod.(*testMethodDescriptor) 42 if !ok { 43 t.Fatalf("The returned method was not of the expected type of %T, but instead it was %T.", testMethod, returnedMethod) 44 } 45 if returnedTypedMethod.id != testMethod.id { 46 t.Fatalf("The returned method contained the wrong ID %s instead of %s", returnedTypedMethod.id, testMethod.id) 47 } 48 49 _, err = reg.GetMethodDescriptor("nonexistent") 50 if err == nil { 51 t.Fatalf("Requesting a non-existent method from GetMethodDescriptor did not return an error.") 52 } 53 var typedErr *registry.MethodNotFoundError 54 if !errors.As(err, &typedErr) { 55 t.Fatalf( 56 "Requesting a non-existent method from GetMethodDescriptor returned an incorrect error type of %T. This function should always return a *registry.MethodNotFoundError if the method was not found.", 57 err, 58 ) 59 } 60 } 61 62 func complianceTestMethodInvalidID(t *testing.T, factory func() registry.Registry) { 63 reg := factory() 64 testMethod := &testMethodDescriptor{ 65 "Hello world!", 66 } 67 err := reg.RegisterMethod(testMethod) 68 if err == nil { 69 t.Fatalf("Registering a method with the invalid ID of %s did not result in an error.", testMethod.id) 70 } 71 var typedErr *registry.InvalidMethodError 72 if !errors.As(err, &typedErr) { 73 t.Fatalf( 74 "Registering a method with an invalid ID of %s resulted in an error of type %T instead of %T. Please make sure to use the correct typed errors.", 75 testMethod.id, 76 err, 77 typedErr, 78 ) 79 } 80 } 81 82 func complianceTestMethodDuplicateRegistration(t *testing.T, factory func() registry.Registry) { 83 reg := factory() 84 testMethod := &testMethodDescriptor{ 85 "test", 86 } 87 testMethod2 := &testMethodDescriptor{ 88 "test", 89 } 90 if err := reg.RegisterMethod(testMethod); err != nil { 91 t.Fatalf("Failed to register test method with ID %s (%v)", testMethod.id, err) 92 } 93 err := reg.RegisterMethod(testMethod) 94 if err == nil { 95 t.Fatalf("Re-registering the same method again did not result in an error.") 96 } 97 var typedErr *registry.MethodAlreadyRegisteredError 98 if !errors.As(err, &typedErr) { 99 t.Fatalf( 100 "Re-registering the same method twice resulted in an error of the type %T instead of %T. Please make sure to use the correct typed errors.", 101 err, 102 typedErr, 103 ) 104 } 105 106 err = reg.RegisterMethod(testMethod2) 107 if err == nil { 108 t.Fatalf("Re-registering the a provider with a duplicate ID did not result in an error.") 109 } 110 if !errors.As(err, &typedErr) { 111 t.Fatalf( 112 "Re-registering the a method with a duplicate ID resulted in an error of the type %T instead of %T. Please make sure to use the correct typed errors.", 113 err, 114 typedErr, 115 ) 116 } 117 } 118 119 type testMethodDescriptor struct { 120 id method.ID 121 } 122 123 func (t testMethodDescriptor) ID() method.ID { 124 return t.id 125 } 126 127 func (t testMethodDescriptor) ConfigStruct() method.Config { 128 return &testMethodConfig{} 129 } 130 131 type testMethodConfig struct { 132 } 133 134 func (t testMethodConfig) Build() (method.Method, error) { 135 return nil, method.ErrInvalidConfiguration{ 136 Cause: fmt.Errorf("build not implemented for test method"), 137 } 138 }