1 package config
2
3 import (
4 "context"
5 "fmt"
6 "os"
7 "reflect"
8 "testing"
9
10 "github.com/aws/aws-sdk-go-v2/aws"
11 "github.com/aws/aws-sdk-go-v2/credentials"
12 )
13
14 func TestConfigs_SharedConfigOptions(t *testing.T) {
15 var options LoadOptions
16 optFns := []func(*LoadOptions) error{
17 WithSharedConfigProfile("profile-name"),
18 WithSharedConfigFiles([]string{"creds-file"}),
19 }
20
21 for _, optFn := range optFns {
22 optFn(&options)
23 }
24
25 _, err := configs{options}.AppendFromLoaders(context.TODO(), []loader{
26 func(ctx context.Context, configs configs) (Config, error) {
27 var profile string
28 var found bool
29 var files []string
30 var err error
31
32 for _, cfg := range configs {
33 if p, ok := cfg.(sharedConfigProfileProvider); ok {
34 profile, found, err = p.getSharedConfigProfile(ctx)
35 if err != nil || !found {
36 return nil, err
37 }
38 }
39 if p, ok := cfg.(sharedConfigFilesProvider); ok {
40 files, found, err = p.getSharedConfigFiles(ctx)
41 if err != nil || !found {
42 return nil, err
43 }
44 }
45 }
46
47 if e, a := "profile-name", profile; e != a {
48 t.Errorf("expect %v profile, got %v", e, a)
49 }
50 if diff := cmpDiff([]string{"creds-file"}, files); len(diff) != 0 {
51 t.Errorf("expect resolved shared config match, got diff: \n %s", diff)
52 }
53
54 return nil, nil
55 },
56 })
57
58 if err != nil {
59 t.Fatalf("expect no error, got %v", err)
60 }
61 }
62
63 func TestConfigs_AppendFromLoaders(t *testing.T) {
64 var options LoadOptions
65 err := WithRegion("mock-region")(&options)
66 if err != nil {
67 t.Fatalf("expect not error, got %v", err)
68 }
69
70 cfgs, err := configs{}.AppendFromLoaders(
71 context.TODO(), []loader{
72 func(ctx context.Context, configs configs) (Config, error) {
73 if e, a := 0, len(configs); e != a {
74 t.Errorf("expect %v configs, got %v", e, a)
75 }
76 return options, nil
77 },
78 })
79
80 if err != nil {
81 t.Fatalf("expect no error, got %v", err)
82 }
83
84 if e, a := 1, len(cfgs); e != a {
85 t.Errorf("expect %v configs, got %v", e, a)
86 }
87
88 if diff := cmpDiff(options, cfgs[0]); len(diff) != 0 {
89 t.Errorf("expect config match, got diff: \n %s", diff)
90 }
91 }
92
93 func TestConfigs_ResolveAWSConfig(t *testing.T) {
94 var options LoadOptions
95 optFns := []func(*LoadOptions) error{
96 WithRegion("mock-region"),
97 WithCredentialsProvider(credentials.StaticCredentialsProvider{
98 Value: aws.Credentials{
99 AccessKeyID: "AKID", SecretAccessKey: "SECRET",
100 Source: "provider",
101 },
102 }),
103 }
104
105 for _, optFn := range optFns {
106 optFn(&options)
107 }
108
109 config := configs{options}
110
111 cfg, err := config.ResolveAWSConfig(context.TODO(), []awsConfigResolver{
112 resolveRegion,
113 resolveCredentials,
114 })
115 if err != nil {
116 t.Fatalf("expect no error, got %v", err)
117 }
118
119 if e, a := "mock-region", cfg.Region; e != a {
120 t.Errorf("expect %v region, got %v", e, a)
121 }
122
123 creds, err := cfg.Credentials.Retrieve(context.TODO())
124 if err != nil {
125 t.Fatalf("expect no error, got %v", err)
126 }
127 if e, a := "provider", creds.Source; e != a {
128 t.Errorf("expect %v provider, got %v", e, a)
129 }
130
131 var expectedSources []interface{}
132 for _, s := range cfg.ConfigSources {
133 expectedSources = append(expectedSources, s)
134 }
135
136 if diff := cmpDiff(expectedSources, cfg.ConfigSources); len(diff) != 0 {
137 t.Errorf("expect config sources match, got diff: \n %s", diff)
138 }
139 }
140
141 func TestLoadDefaultConfig(t *testing.T) {
142 optWithErr := func(_ *LoadOptions) error {
143 return fmt.Errorf("some error")
144 }
145 _, err := LoadDefaultConfig(context.TODO(), optWithErr)
146 if err == nil {
147 t.Fatal("expect error when optFn returns error, got nil")
148 }
149 }
150
151 func BenchmarkLoadProfile1(b *testing.B) {
152 benchConfigLoad(b, 1)
153 }
154
155 func BenchmarkLoadProfile10(b *testing.B) {
156 benchConfigLoad(b, 10)
157 }
158
159 func BenchmarkLoadProfile100(b *testing.B) {
160 benchConfigLoad(b, 100)
161 }
162
163 func BenchmarkLoadProfile1000(b *testing.B) {
164 benchConfigLoad(b, 1000)
165 }
166
167 func benchConfigLoad(b *testing.B, n int) {
168 f, err := generateProfiles(n)
169 if err != nil {
170 b.Fatal(err)
171 }
172
173 defer os.Remove(f)
174 opt := WithSharedConfigFiles([]string{f})
175
176 b.ResetTimer()
177 for n := 0; n < b.N; n++ {
178 LoadDefaultConfig(context.Background(), opt)
179 }
180 }
181
182 const profileTemplate = `
183 [profile role%d]
184 tool_sso_start_url = https://example.awsapps.com/start
185 tool_sso_region = us-west-2
186 tool_sso_account_id = 12345678901234
187 tool_sso_role_name = some_role_name
188 tool_generated_from = some_tool
189 credential_process = some_tool credential-process
190 `
191
192 func generateProfiles(n int) (string, error) {
193 f, err := os.CreateTemp("", fmt.Sprintf("aws-bench-config-%d-*", n))
194 if err != nil {
195 return "", err
196 }
197
198 for i := 0; i < n; i++ {
199 if _, err := fmt.Fprintf(f, profileTemplate, n); err != nil {
200 f.Close()
201 os.Remove(f.Name())
202 return "", err
203 }
204 }
205
206 if err := f.Close(); err != nil {
207 os.Remove(f.Name())
208 return "", err
209 }
210
211 return f.Name(), nil
212 }
213
214 func cmpDiff(e, a interface{}) string {
215 if !reflect.DeepEqual(e, a) {
216 return fmt.Sprintf("%v != %v", e, a)
217 }
218 return ""
219 }
220
View as plain text