@@ -33,19 +33,84 @@ import (
33
33
// In particular, it lets one test cover a range of different source/dest types, and even cover both sync and copy.
34
34
// See first test in zt_enumeration for an annotated example.
35
35
36
+ var validCredTypesPerLocation = map [common.Location ][]common.CredentialType {
37
+ common .ELocation .Unknown (): {common .ECredentialType .Unknown (), common .ECredentialType .Anonymous (), common .ECredentialType .OAuthToken ()}, // Delete!
38
+ common .ELocation .File (): {common .ECredentialType .Anonymous ()},
39
+ common .ELocation .Blob (): {common .ECredentialType .Anonymous (), common .ECredentialType .OAuthToken ()},
40
+ common .ELocation .BlobFS (): {common .ECredentialType .Anonymous (), common .ECredentialType .OAuthToken ()}, // todo: currently, account key auth isn't even supported in e2e tests.
41
+ common .ELocation .Local (): {common .ECredentialType .Anonymous ()},
42
+ common .ELocation .Pipe (): {common .ECredentialType .Anonymous ()},
43
+ common .ELocation .S3 (): {common .ECredentialType .S3AccessKey ()},
44
+ common .ELocation .GCP (): {common .ECredentialType .GoogleAppCredentials ()},
45
+ }
46
+
47
+ var allCredentialTypes []common.CredentialType = nil
48
+ var anonymousAuthOnly = []common.CredentialType {common .ECredentialType .Anonymous ()}
49
+
50
+ func getValidCredCombinationsForFromTo (fromTo common.FromTo , requestedCredentialTypesSrc , requestedCredentialTypesDst []common.CredentialType ) [][2 ]common.CredentialType {
51
+ output := make ([][2 ]common.CredentialType , 0 )
52
+
53
+ credIsRequested := func (cType common.CredentialType , dst bool ) bool {
54
+ if (dst && requestedCredentialTypesDst == nil ) || (! dst && requestedCredentialTypesSrc == nil ) {
55
+ return true
56
+ }
57
+
58
+ toSearch := requestedCredentialTypesSrc
59
+ if dst {
60
+ toSearch = requestedCredentialTypesDst
61
+ }
62
+
63
+ for _ , v := range toSearch {
64
+ if v == cType {
65
+ return true
66
+ }
67
+ }
68
+
69
+ return false
70
+ }
71
+
72
+ // determine source types
73
+ var sourceTypes []common.CredentialType
74
+ if fromTo .IsS2S () {
75
+ // source must always be anonymous-- no exceptions until OAuth over S2S is introduced.
76
+ sourceTypes = []common.CredentialType {common .ECredentialType .Anonymous ()}
77
+ } else {
78
+ sourceTypes = validCredTypesPerLocation [fromTo .From ()]
79
+ }
80
+
81
+ for _ , srcCredType := range sourceTypes {
82
+ for _ , dstCredType := range validCredTypesPerLocation [fromTo .To ()] {
83
+ // make sure the user asked for this.
84
+ if ! (credIsRequested (srcCredType , false ) && credIsRequested (dstCredType , true )) {
85
+ continue
86
+ }
87
+
88
+ output = append (output , [2 ]common.CredentialType {srcCredType , dstCredType })
89
+ }
90
+ }
91
+
92
+ return output
93
+ }
94
+
36
95
// RunScenarios is the key entry point for declarative testing.
37
96
// It constructs and executes scenarios (subtest in Go-speak), according to its parameters, and checks their results
38
97
func RunScenarios (
39
98
t * testing.T ,
40
99
operations Operation ,
41
100
testFromTo TestFromTo ,
42
101
validate Validate , // TODO: do we really want the test author to have to nominate which validation should happen? Pros: better perf of tests. Cons: they have to tell us, and if they tell us wrong test may not test what they think it tests
43
- /*_ interface{}, // TODO if we want it??, blockBLobsOnly or specifc/all blob types
44
- _ interface{}, // TODO if we want it??, default auth type only, or specific/all auth types*/
102
+ // _ interface{}, // TODO if we want it??, blockBLobsOnly or specifc/all blob types
103
+
104
+ // It would be a pain to list out every combo by hand,
105
+ // In addition to the fact that not every credential type is sensible.
106
+ // Thus, the E2E framework takes in a requested set of credential types, and applies them where sensible.
107
+ // This allows you to make tests use OAuth only, SAS only, etc.
108
+ requestedCredentialTypesSrc []common.CredentialType ,
109
+ requestedCredentialTypesDst []common.CredentialType ,
45
110
p params ,
46
111
hs * hooks ,
47
112
fs testFiles ,
48
- // TODO: do we need something here to explicitly say that we expect success or failure? For now, we are just inferring that from the elements of sourceFiles
113
+ // TODO: do we need something here to explicitly say that we expect success or failure? For now, we are just inferring that from the elements of sourceFiles
49
114
destAccountType AccountType ,
50
115
accountType AccountType ,
51
116
scenarioSuffix string ) {
@@ -58,7 +123,7 @@ func RunScenarios(
58
123
}
59
124
60
125
// construct all the scenarios
61
- scenarios := make ([]scenario , 0 , 16 )
126
+ scenarios := make ([]scenario , 0 )
62
127
for _ , op := range operations .getValues () {
63
128
if op == eOperation .Resume () {
64
129
continue
@@ -73,44 +138,50 @@ func RunScenarios(
73
138
}
74
139
seenFromTos [fromTo ] = true
75
140
76
- // Create unique name for generating container names
77
- compactScenarioName := fmt .Sprintf ("%.4s-%s-%c-%c%c" , suiteName , testName , op .String ()[0 ], fromTo .From ().String ()[0 ], fromTo .To ().String ()[0 ])
78
- fullScenarioName := fmt .Sprintf ("%s.%s.%s-%s" , suiteName , testName , op .String (), fromTo .String ())
141
+ credentialTypes := getValidCredCombinationsForFromTo (fromTo , requestedCredentialTypesSrc , requestedCredentialTypesDst )
79
142
80
- // Sub-test name is not globally unique (it doesn't need to be) but it is more human-readable
81
- subtestName := fmt .Sprintf ("%s-%s" , op , fromTo )
82
- if scenarioSuffix != "" {
83
- subtestName += "-" + scenarioSuffix
84
- }
143
+ for _ , credTypes := range credentialTypes {
144
+ // Create unique name for generating container names
145
+ compactScenarioName := fmt .Sprintf ("%.4s-%s-%c-%c%c" , suiteName , testName , op .String ()[0 ], fromTo .From ().String ()[0 ], fromTo .To ().String ()[0 ])
146
+ fullScenarioName := fmt .Sprintf ("%s.%s.%s-%s" , suiteName , testName , op .String (), fromTo .String ())
147
+ // Sub-test name is not globally unique (it doesn't need to be) but it is more human-readable
148
+ subtestName := fmt .Sprintf ("%s-%s" , op , fromTo )
85
149
86
- hsToUse := hooks {}
87
- if hs != nil {
88
- hsToUse = * hs
89
- }
150
+ hsToUse := hooks {}
151
+ if hs != nil {
152
+ hsToUse = * hs
153
+ }
90
154
91
- // Handles destination being different account type
92
- isSourceAcc := true
93
- if destAccountType != accountType {
94
- isSourceAcc = false
95
- }
96
- s := scenario {
97
- srcAccountType : accountType ,
98
- destAccountType : destAccountType ,
99
- subtestName : subtestName ,
100
- compactScenarioName : compactScenarioName ,
101
- fullScenarioName : fullScenarioName ,
102
- operation : op ,
103
- fromTo : fromTo ,
104
- validate : validate ,
105
- p : p , // copies them, because they are a struct. This is what we need, since they may be morphed while running
106
- hs : hsToUse ,
107
- fs : fs .DeepCopy (),
108
- needResume : operations & eOperation .Resume () != 0 ,
109
- stripTopDir : p .stripTopDir ,
110
- isSourceAcc : isSourceAcc ,
111
- }
155
+ if scenarioSuffix != "" {
156
+ subtestName += "-" + scenarioSuffix
157
+ }
112
158
113
- scenarios = append (scenarios , s )
159
+ // Handles destination being different account type
160
+ isSourceAcc := true
161
+ if destAccountType != accountType {
162
+ isSourceAcc = false
163
+ }
164
+
165
+ s := scenario {
166
+ srcAccountType : accountType ,
167
+ destAccountType : destAccountType ,
168
+ subtestName : subtestName ,
169
+ compactScenarioName : compactScenarioName ,
170
+ fullScenarioName : fullScenarioName ,
171
+ operation : op ,
172
+ fromTo : fromTo ,
173
+ credTypes : credTypes ,
174
+ validate : validate ,
175
+ p : p , // copies them, because they are a struct. This is what we need, since they may be morphed while running
176
+ hs : hsToUse ,
177
+ fs : fs .DeepCopy (),
178
+ needResume : operations & eOperation .Resume () != 0 ,
179
+ stripTopDir : p .stripTopDir ,
180
+ isSourceAcc : isSourceAcc ,
181
+ }
182
+
183
+ scenarios = append (scenarios , s )
184
+ }
114
185
}
115
186
}
116
187
@@ -122,22 +193,28 @@ func RunScenarios(
122
193
// run them in parallel if not debugging, but sequentially (for easier debugging) if a debugger is attached
123
194
parallel := ! isLaunchedByDebugger && ! p .disableParallelTesting // this only works if gops.exe is on your path. See azcopyDebugHelper.go for instructions.
124
195
for _ , s := range scenarios {
125
- sen := s // capture to separate var inside the loop, for the parallel case
126
196
// use t.Run to get proper sub-test support
127
197
t .Run (s .subtestName , func (t * testing.T ) {
128
- if parallel {
129
- t .Parallel () // tell testing that it can run stuff in parallel with us
130
- }
131
- // set asserter now (and only now), since before this point we don't have the right "t"
132
- sen .a = & testingAsserter {
133
- t : t ,
134
- fullScenarioName : sen .fullScenarioName ,
135
- compactScenarioName : sen .compactScenarioName ,
136
- }
137
- if hs != nil {
138
- sen .runHook (hs .beforeTestRun )
139
- }
140
- sen .Run ()
198
+ sen := s // capture to separate var inside the loop, for the parallel case
199
+ credNames := fmt .Sprintf ("%s-%s" , s .credTypes [0 ].String (), s .credTypes [1 ].String ())
200
+
201
+ t .Run (credNames , func (t * testing.T ) {
202
+ if parallel {
203
+ t .Parallel () // tell testing that it can run stuff in parallel with us
204
+ }
205
+ // set asserter now (and only now), since before this point we don't have the right "t"
206
+ sen .a = & testingAsserter {
207
+ t : t ,
208
+ fullScenarioName : sen .fullScenarioName ,
209
+ compactScenarioName : sen .compactScenarioName ,
210
+ }
211
+
212
+ if hs != nil {
213
+ sen .runHook (hs .beforeTestRun )
214
+ }
215
+
216
+ sen .Run ()
217
+ })
141
218
})
142
219
}
143
220
}
0 commit comments