1
1
package storage
2
2
3
3
import (
4
+ "bytes"
4
5
"context"
5
6
"errors"
6
7
"fmt"
@@ -15,7 +16,10 @@ import (
15
16
"testing"
16
17
"testing/fstest"
17
18
19
+ "github.com/stretchr/testify/assert"
18
20
"github.com/stretchr/testify/require"
21
+
22
+ "github.com/operator-framework/operator-registry/alpha/declcfg"
19
23
)
20
24
21
25
const urlPrefix = "/catalogs/"
@@ -170,14 +174,10 @@ func TestLocalDirStoraget(t *testing.T) {
170
174
171
175
func TestLocalDirServerHandler (t * testing.T ) {
172
176
store := & LocalDirV1 {RootDir : t .TempDir (), RootURL : & url.URL {Path : urlPrefix }}
173
- testFS := fstest.MapFS {
174
- "meta.json" : & fstest.MapFile {
175
- Data : []byte (`{"foo":"bar"}` ),
176
- },
177
- }
178
- if store .Store (context .Background (), "test-catalog" , testFS ) != nil {
177
+ if store .Store (context .Background (), "test-catalog" , createTestFS (t )) != nil {
179
178
t .Fatal ("failed to store test catalog and start server" )
180
179
}
180
+
181
181
testServer := httptest .NewServer (store .StorageServerHandler ())
182
182
defer testServer .Close ()
183
183
@@ -242,10 +242,12 @@ func TestLocalDirServerHandler(t *testing.T) {
242
242
URLPath : "/catalogs/non-existent-catalog/api/v1/all" ,
243
243
},
244
244
{
245
- name : "Server returns 200 when path '/catalogs/<catalog>/api/v1/all' is queried, when catalog exists" ,
245
+ name : "Server returns 200 with json-lines payload when path '/catalogs/<catalog>/api/v1/all' is queried, when catalog exists" ,
246
246
expectedStatusCode : http .StatusOK ,
247
- expectedContent : `{"foo":"bar"}` ,
248
- URLPath : "/catalogs/test-catalog/api/v1/all" ,
247
+ expectedContent : `{"image":"quaydock.io/namespace/bundle:0.0.3","name":"bundle.v0.0.1","package":"webhook_operator_test","properties":[{"type":"olm.bundle.object","value":{"data":"dW5pbXBvcnRhbnQK"}},{"type":"some.other","value":{"data":"arbitrary-info"}}],"relatedImages":[{"image":"testimage:latest","name":"test"}],"schema":"olm.bundle"}` + "\n " +
248
+ `{"defaultChannel":"preview_test","name":"webhook_operator_test","schema":"olm.package"}` + "\n " +
249
+ `{"entries":[{"name":"bundle.v0.0.1"}],"name":"preview_test","package":"webhook_operator_test","schema":"olm.channel"}` ,
250
+ URLPath : "/catalogs/test-catalog/api/v1/all" ,
249
251
},
250
252
} {
251
253
t .Run (tc .name , func (t * testing.T ) {
@@ -256,11 +258,14 @@ func TestLocalDirServerHandler(t *testing.T) {
256
258
require .NoError (t , err )
257
259
258
260
require .Equal (t , tc .expectedStatusCode , resp .StatusCode )
261
+ if resp .StatusCode == http .StatusOK {
262
+ assert .Equal (t , "application/jsonl" , resp .Header .Get ("Content-Type" ))
263
+ }
259
264
260
- var actualContent []byte
261
- actualContent , err = io .ReadAll (resp .Body )
265
+ actualContent , err := io .ReadAll (resp .Body )
262
266
require .NoError (t , err )
263
- require .Equal (t , tc .expectedContent , strings .TrimSpace (string (actualContent )))
267
+
268
+ require .Equal (t , strings .TrimSpace (tc .expectedContent ), strings .TrimSpace (string (actualContent )))
264
269
require .NoError (t , resp .Body .Close ())
265
270
})
266
271
}
@@ -329,7 +334,7 @@ func TestMetasEndpoint(t *testing.T) {
329
334
expectedContent : "" ,
330
335
},
331
336
{
332
- name : "valid query with packageName that returns multiple blobs" ,
337
+ name : "valid query with packageName that returns multiple blobs in json-lines format " ,
333
338
queryParams : "?package=webhook_operator_test" ,
334
339
expectedStatusCode : http .StatusOK ,
335
340
expectedContent : `{"image":"quaydock.io/namespace/bundle:0.0.3","name":"bundle.v0.0.1","package":"webhook_operator_test","properties":[{"type":"olm.bundle.object","value":{"data":"dW5pbXBvcnRhbnQK"}},{"type":"some.other","value":{"data":"arbitrary-info"}}],"relatedImages":[{"image":"testimage:latest","name":"test"}],"schema":"olm.bundle"}
@@ -377,6 +382,9 @@ func TestMetasEndpoint(t *testing.T) {
377
382
defer resp .Body .Close ()
378
383
379
384
require .Equal (t , tc .expectedStatusCode , resp .StatusCode )
385
+ if resp .StatusCode == http .StatusOK {
386
+ assert .Equal (t , "application/jsonl" , resp .Header .Get ("Content-Type" ))
387
+ }
380
388
381
389
actualContent , err := io .ReadAll (resp .Body )
382
390
require .NoError (t , err )
@@ -591,8 +599,38 @@ entries:
591
599
testBundle := fmt .Sprintf (testBundleTemplate , testBundleImage , testBundleName , testPackageName , testBundleRelatedImageName , testBundleRelatedImageImage , testBundleObjectData )
592
600
testChannel := fmt .Sprintf (testChannelTemplate , testPackageName , testChannelName , testBundleName )
593
601
return & fstest.MapFS {
594
- "bundle.yaml" : {Data : []byte (testBundle ), Mode : os .ModePerm },
595
- "package.yaml" : {Data : []byte (testPackage ), Mode : os .ModePerm },
596
- "channel.yaml" : {Data : []byte (testChannel ), Mode : os .ModePerm },
602
+ "test-catalog.yaml" : {Data : []byte (
603
+ generateJSONLinesOrFail (t , []byte (testBundle )) +
604
+ generateJSONLinesOrFail (t , []byte (testPackage )) +
605
+ generateJSONLinesOrFail (t , []byte (testChannel ))),
606
+ Mode : os .ModePerm },
597
607
}
598
608
}
609
+
610
+ // generateJSONLinesOrFail takes a byte slice of concatenated JSON objects and returns a JSONlines-formatted string
611
+ // or raises a test failure in case of encountering any internal errors
612
+ func generateJSONLinesOrFail (t * testing.T , in []byte ) string {
613
+ var out strings.Builder
614
+ reader := bytes .NewReader (in )
615
+
616
+ err := declcfg .WalkMetasReader (reader , func (meta * declcfg.Meta , err error ) error {
617
+ if err != nil {
618
+ return err
619
+ }
620
+
621
+ if meta != nil && meta .Blob != nil {
622
+ if meta .Blob [len (meta .Blob )- 1 ] != '\n' {
623
+ return fmt .Errorf ("blob does not end with newline" )
624
+ }
625
+ }
626
+
627
+ _ , err = out .Write (meta .Blob )
628
+ if err != nil {
629
+ return err
630
+ }
631
+ return nil
632
+ })
633
+ require .NoError (t , err )
634
+
635
+ return out .String ()
636
+ }
0 commit comments