@@ -20,6 +20,7 @@ import (
2020 "github.com/stretchr/testify/require"
2121
2222 "github.com/ARM-software/embedded-development-services-client/client"
23+ "github.com/ARM-software/golang-utils/utils/collection"
2324 "github.com/ARM-software/golang-utils/utils/commonerrors"
2425 "github.com/ARM-software/golang-utils/utils/commonerrors/errortest"
2526 "github.com/ARM-software/golang-utils/utils/field"
@@ -28,14 +29,21 @@ import (
2829 "github.com/ARM-software/golang-utils/utils/safeio"
2930)
3031
32+ type (
33+ testGetArtefactManagersFirstPageFunc = func (ctx context.Context , _ string ) (a * client.ArtefactManagerCollection , resp * http.Response , err error )
34+ testGetArtefactManagerFunc = func (ctx context.Context , job , artefact string ) (* client.ArtefactManagerItem , * http.Response , error )
35+ testGetArtefactContentFunc = func (ctx context.Context , job , artefactID string ) (* os.File , * http.Response , error )
36+ )
37+
3138type testArtefact struct {
3239 name string
3340 path string
3441 embeddedResource bool
42+ shouldFail bool
3543}
3644
37- func newTestArtefact (t * testing.T , tmpDir , artefactContent string , embeddedResource bool ) * testArtefact {
38- path , err := filesystem .TouchTempFile (tmpDir , "artefact" )
45+ func newTestArtefact (t * testing.T , tmpDir , artefactContent string , embeddedResource bool , shouldFail bool ) * testArtefact {
46+ path , err := filesystem .TouchTempFile (tmpDir , fmt . Sprintf ( "artefact-%s" , faker . Word ()) )
3947 require .NoError (t , err )
4048 if len (artefactContent ) > 0 {
4149 err = filesystem .WriteFile (path , []byte (artefactContent ), 0777 )
@@ -48,67 +56,10 @@ func newTestArtefact(t *testing.T, tmpDir, artefactContent string, embeddedResou
4856 name : filepath .Base (path ),
4957 path : path ,
5058 embeddedResource : embeddedResource ,
59+ shouldFail : shouldFail ,
5160 }
5261}
5362
54- func (t * testArtefact ) testGetArtefactManagers (ctx context.Context , _ string ) (a * client.ArtefactManagerCollection , resp * http.Response , err error ) {
55- item , err := t .fetchTestArtefact (ctx )
56- if err != nil {
57- return
58- }
59- if t .embeddedResource {
60- a = & client.ArtefactManagerCollection {
61- Embedded : & client.EmbeddedArtefactManagerItems {Item : []client.ArtefactManagerItem {* item }},
62- Links : * client .NewNullableHalCollectionLinks (client .NewHalCollectionLinksWithDefaults ()),
63- Metadata : * client .NewNullablePagingMetadata (& client.PagingMetadata {
64- Count : 1 ,
65- Ctime : time .Now (),
66- Etime : client.NullableTime {},
67- Limit : 6 ,
68- Mtime : time .Now (),
69- Offset : 0 ,
70- Total : 1 ,
71- }),
72- Name : "list of artefacts" ,
73- Title : faker .Name (),
74- }
75- } else {
76- links := client .NewHalCollectionLinksWithDefaults ()
77- links .Item = []client.HalLinkData {client.HalLinkData {
78- Href : fmt .Sprintf ("/test/%v" , item .Name ),
79- Name : field .ToOptionalString (item .Name ),
80- Title : field .ToOptionalString (faker .Name ()),
81- }}
82- a = & client.ArtefactManagerCollection {
83- Embedded : nil ,
84- Links : * client .NewNullableHalCollectionLinks (links ),
85- Metadata : * client .NewNullablePagingMetadata (& client.PagingMetadata {
86- Count : 1 ,
87- Ctime : time .Now (),
88- Etime : client.NullableTime {},
89- Limit : 6 ,
90- Mtime : time .Now (),
91- Offset : 0 ,
92- Total : 1 ,
93- }),
94- Name : "list of artefacts" ,
95- Title : faker .Name (),
96- }
97- }
98- resp = & http.Response {StatusCode : http .StatusOK , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}
99- return
100- }
101-
102- func (t * testArtefact ) testGetArtefactManager (ctx context.Context , _ , artefact string ) (a * client.ArtefactManagerItem , resp * http.Response , err error ) {
103- if artefact == t .name {
104- a , err = t .fetchTestArtefact (ctx )
105- resp = & http.Response {StatusCode : http .StatusOK , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}
106- } else {
107- err = commonerrors .ErrNotFound
108- }
109- return
110- }
111-
11263func (t * testArtefact ) fetchTestArtefact (ctx context.Context ) (a * client.ArtefactManagerItem , err error ) {
11364 fileHasher , subErr := filesystem .NewFileHash (hashing .HashSha256 )
11465 if subErr != nil {
@@ -143,28 +94,155 @@ func (t *testArtefact) fetchTestArtefact(ctx context.Context) (a *client.Artefac
14394 return
14495}
14596
146- func (t * testArtefact ) testGetOutputArtefact (ctx context.Context , _ , artefact string ) (f * os.File , resp * http.Response , err error ) {
147- if artefact == t .name {
97+ func testGetArtefactManager (t * testing.T , artefacts []* testArtefact ) testGetArtefactManagerFunc {
98+ t .Helper ()
99+ if len (artefacts ) == 0 {
100+ return nil
101+ }
102+
103+ names := collection .Map (artefacts , func (a * testArtefact ) string {
104+ return a .name
105+ })
106+
107+ return func (ctx context.Context , _ , artefact string ) (a * client.ArtefactManagerItem , resp * http.Response , err error ) {
108+ artefactIdx , found := collection .Find (& names , artefact )
109+ if ! found {
110+ err = commonerrors .ErrNotFound
111+ return
112+ }
113+ t := artefacts [artefactIdx ]
114+ a , err = t .fetchTestArtefact (ctx )
115+ resp = & http.Response {StatusCode : http .StatusOK , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}
116+ return
117+
118+ }
119+ }
120+
121+ func testGetOutputArtefact (t * testing.T , artefacts []* testArtefact ) testGetArtefactContentFunc {
122+ t .Helper ()
123+ if len (artefacts ) == 0 {
124+ return nil
125+ }
126+
127+ names := collection .Map (artefacts , func (a * testArtefact ) string {
128+ return a .name
129+ })
130+
131+ return func (ctx context.Context , _ , artefact string ) (f * os.File , resp * http.Response , err error ) {
132+ artefactIdx , found := collection .Find (& names , artefact )
133+ if ! found {
134+ return nil , & http.Response {StatusCode : http .StatusNotFound , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}, commonerrors .ErrNotFound
135+ }
136+
137+ t := artefacts [artefactIdx ]
138+
139+ if t .shouldFail {
140+ return nil , & http.Response {StatusCode : http .StatusInternalServerError , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}, commonerrors .ErrUnexpected
141+ }
142+
148143 f , err = os .Open (t .path )
149144 if err != nil {
150145 return
151146 }
152147
153148 return f , & http.Response {StatusCode : http .StatusOK , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}, nil
154149 }
155-
156- return nil , & http.Response {StatusCode : http .StatusNotFound , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}, commonerrors .ErrNotFound
157150}
158151
159- func newTestArtefactManager (t * testing.T , tmpDir , artefactContent string , linksOnly bool ) (IArtefactManager [* client.ArtefactManagerItem , * client.HalLinkData ], * testArtefact ) {
160- testArtefact := newTestArtefact (t , tmpDir , artefactContent , ! linksOnly )
161- return NewArtefactManager (testArtefact .testGetArtefactManagers , nil , testArtefact .testGetArtefactManager , testArtefact .testGetOutputArtefact ), testArtefact
152+ func testGetArtefactManagers (t * testing.T , artefacts []* testArtefact , embeddedResource bool ) testGetArtefactManagersFirstPageFunc {
153+ t .Helper ()
154+ if len (artefacts ) == 0 {
155+ return nil
156+ }
157+
158+ return func (ctx context.Context , _ string ) (a * client.ArtefactManagerCollection , resp * http.Response , err error ) {
159+ count := int32 (len (artefacts ))
160+ if embeddedResource {
161+ items , mapErr := collection .MapWithError (artefacts , func (artefact * testArtefact ) (client.ArtefactManagerItem , error ) {
162+ item , err := artefact .fetchTestArtefact (ctx )
163+ if err != nil {
164+ return client.ArtefactManagerItem {}, err
165+ }
166+
167+ return * item , nil
168+ })
169+
170+ if mapErr != nil {
171+ err = mapErr
172+ return
173+ }
174+
175+ a = & client.ArtefactManagerCollection {
176+ Embedded : & client.EmbeddedArtefactManagerItems {Item : items },
177+ Links : * client .NewNullableHalCollectionLinks (client .NewHalCollectionLinksWithDefaults ()),
178+ Metadata : * client .NewNullablePagingMetadata (& client.PagingMetadata {
179+ Count : count ,
180+ Ctime : time .Now (),
181+ Etime : client.NullableTime {},
182+ Limit : 6 ,
183+ Mtime : time .Now (),
184+ Offset : 0 ,
185+ Total : count ,
186+ }),
187+ Name : "list of artefacts" ,
188+ Title : faker .Name (),
189+ }
190+ } else {
191+ items , mapErr := collection .MapWithError (artefacts , func (artefact * testArtefact ) (client.HalLinkData , error ) {
192+ item , err := artefact .fetchTestArtefact (ctx )
193+ if err != nil {
194+ return client.HalLinkData {}, err
195+ }
196+
197+ return client.HalLinkData {
198+ Href : fmt .Sprintf ("/test/%v" , item .Name ),
199+ Name : field .ToOptionalString (item .Name ),
200+ Title : field .ToOptionalString (faker .Name ()),
201+ }, nil
202+ })
203+
204+ if mapErr != nil {
205+ err = mapErr
206+ return
207+ }
208+
209+ links := client .NewHalCollectionLinksWithDefaults ()
210+ links .Item = items
211+ a = & client.ArtefactManagerCollection {
212+ Embedded : nil ,
213+ Links : * client .NewNullableHalCollectionLinks (links ),
214+ Metadata : * client .NewNullablePagingMetadata (& client.PagingMetadata {
215+ Count : count ,
216+ Ctime : time .Now (),
217+ Etime : client.NullableTime {},
218+ Limit : 6 ,
219+ Mtime : time .Now (),
220+ Offset : 0 ,
221+ Total : count ,
222+ }),
223+ Name : "list of artefacts" ,
224+ Title : faker .Name (),
225+ }
226+ }
227+ resp = & http.Response {StatusCode : http .StatusOK , Body : io .NopCloser (safeio .NewByteReader (ctx , []byte ("hello" )))}
228+ return
229+ }
162230}
163231
164232func newTestArtefactManagerWithEmbeddedResources (t * testing.T , tmpDir , artefactContent string ) (IArtefactManager [* client.ArtefactManagerItem , * client.HalLinkData ], * testArtefact ) {
165233 return newTestArtefactManager (t , tmpDir , artefactContent , false )
166234}
167235
236+ func newTestArtefactManager (t * testing.T , tmpDir , artefactContent string , linksOnly bool ) (IArtefactManager [* client.ArtefactManagerItem , * client.HalLinkData ], * testArtefact ) {
237+ artefact := newTestArtefact (t , tmpDir , artefactContent , ! linksOnly , false )
238+ artefacts := []* testArtefact {artefact }
239+ return newTestArtefactsManager (t , artefacts , linksOnly ), artefact
240+ }
241+
242+ func newTestArtefactsManager (t * testing.T , artefacts []* testArtefact , linksOnly bool ) IArtefactManager [* client.ArtefactManagerItem , * client.HalLinkData ] {
243+ return NewArtefactManager (testGetArtefactManagers (t , artefacts , ! linksOnly ), nil , testGetArtefactManager (t , artefacts ), testGetOutputArtefact (t , artefacts ))
244+ }
245+
168246func TestDetermineDestination (t * testing.T ) {
169247 outputDir := strings .ReplaceAll (faker .Sentence (), " " , "//" ) + " "
170248 cleanedOutputDir := filepath .Clean (outputDir )
@@ -292,6 +370,48 @@ func TestArtefactDownload(t *testing.T) {
292370 require .NoError (t , err )
293371 assert .Equal (t , expectedContents , actualContents )
294372 })
373+ t .Run ("Stop on first download error" , func (t * testing.T ) {
374+ tmpDir , err := filesystem .TempDirInTempDir ("test-artefact-" )
375+ require .NoError (t , err )
376+ defer func () { _ = filesystem .Rm (tmpDir ) }()
377+ artefacts := []* testArtefact {
378+ newTestArtefact (t , tmpDir , faker .Sentence (), true , false ),
379+ newTestArtefact (t , tmpDir , faker .Sentence (), true , true ),
380+ newTestArtefact (t , tmpDir , faker .Sentence (), true , false ),
381+ }
382+ manager := newTestArtefactsManager (t , artefacts , false )
383+
384+ out := t .TempDir ()
385+ err = manager .DownloadAllJobArtefactsWithOptions (context .Background (), faker .Word (), out , WithStopOnFirstError (true ))
386+ require .Error (t , err )
387+ assert .ErrorIs (t , err , commonerrors .ErrUnexpected )
388+
389+ require .FileExists (t , filepath .Join (out , artefacts [0 ].name ))
390+ assert .NoFileExists (t , filepath .Join (out , artefacts [1 ].name ))
391+ assert .NoFileExists (t , filepath .Join (out , artefacts [2 ].name ))
392+ })
393+
394+ t .Run ("Continue on download error" , func (t * testing.T ) {
395+ tmpDir , err := filesystem .TempDirInTempDir ("test-artefact-" )
396+ require .NoError (t , err )
397+ defer func () { _ = filesystem .Rm (tmpDir ) }()
398+ artefacts := []* testArtefact {
399+ newTestArtefact (t , tmpDir , faker .Sentence (), true , false ),
400+ newTestArtefact (t , tmpDir , faker .Sentence (), true , true ),
401+ newTestArtefact (t , tmpDir , faker .Sentence (), true , false ),
402+ }
403+ manager := newTestArtefactsManager (t , artefacts , false )
404+
405+ out := t .TempDir ()
406+ err = manager .DownloadAllJobArtefactsWithOptions (context .Background (), faker .Word (), out , WithStopOnFirstError (false ))
407+ require .Error (t , err )
408+ assert .ErrorIs (t , err , commonerrors .ErrUnexpected )
409+
410+ require .FileExists (t , filepath .Join (out , artefacts [0 ].name ))
411+ assert .NoFileExists (t , filepath .Join (out , artefacts [1 ].name ))
412+ assert .FileExists (t , filepath .Join (out , artefacts [2 ].name ))
413+
414+ })
295415 t .Run ("Happy download artefact and keep tree" , func (t * testing.T ) {
296416 tmpDir , err := filesystem .TempDirInTempDir ("test-artefact-with-tree-" )
297417 require .NoError (t , err )
0 commit comments