Skip to content

Commit bb3d178

Browse files
authored
test: increase unit test coverage to 80% (#876)
1. Increase unit test coverage to 80% 2. Set Codecov threshold to 80% Resolves: #779 Signed-off-by: Lixia (Sylvia) Lei <lixlei@microsoft.com>
1 parent dff5628 commit bb3d178

File tree

13 files changed

+2022
-305
lines changed

13 files changed

+2022
-305
lines changed

.github/.codecov.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ coverage:
1515
status:
1616
project:
1717
default:
18-
target: 75%
18+
target: 80%
1919
if_ci_failed: error
2020
patch:
2121
default:

content/graph_test.go

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@ import (
1919
"bytes"
2020
"context"
2121
"encoding/json"
22+
"errors"
2223
"reflect"
2324
"testing"
2425

2526
"github.com/opencontainers/go-digest"
2627
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
2728
"oras.land/oras-go/v2/content"
29+
"oras.land/oras-go/v2/errdef"
2830
"oras.land/oras-go/v2/internal/cas"
2931
"oras.land/oras-go/v2/internal/docker"
3032
"oras.land/oras-go/v2/internal/spec"
@@ -389,3 +391,100 @@ func TestSuccessors_otherMediaType(t *testing.T) {
389391
t.Errorf("Successors() = %v, want nil", got)
390392
}
391393
}
394+
395+
func TestSuccessors_ErrNotFound(t *testing.T) {
396+
tests := []struct {
397+
name string
398+
desc ocispec.Descriptor
399+
}{
400+
{
401+
name: "docker manifest",
402+
desc: ocispec.Descriptor{
403+
MediaType: docker.MediaTypeManifest,
404+
},
405+
},
406+
{
407+
name: "image manifest",
408+
desc: ocispec.Descriptor{
409+
MediaType: ocispec.MediaTypeImageManifest,
410+
},
411+
},
412+
{
413+
name: "docker manifest list",
414+
desc: ocispec.Descriptor{
415+
MediaType: docker.MediaTypeManifestList,
416+
},
417+
},
418+
{
419+
name: "image index",
420+
desc: ocispec.Descriptor{
421+
MediaType: ocispec.MediaTypeImageIndex,
422+
},
423+
},
424+
{
425+
name: "artifact manifest",
426+
desc: ocispec.Descriptor{
427+
MediaType: spec.MediaTypeArtifactManifest,
428+
},
429+
},
430+
}
431+
for _, tt := range tests {
432+
t.Run(tt.name, func(t *testing.T) {
433+
ctx := context.Background()
434+
fetcher := cas.NewMemory()
435+
if _, err := content.Successors(ctx, fetcher, tt.desc); !errors.Is(err, errdef.ErrNotFound) {
436+
t.Errorf("Successors() error = %v, wantErr = %v", err, errdef.ErrNotFound)
437+
}
438+
})
439+
}
440+
}
441+
442+
func TestSuccessors_UnmarshalError(t *testing.T) {
443+
tests := []struct {
444+
name string
445+
mediaType string
446+
}{
447+
{
448+
name: "docker manifest",
449+
mediaType: docker.MediaTypeManifest,
450+
},
451+
{
452+
name: "image manifest",
453+
mediaType: ocispec.MediaTypeImageManifest,
454+
},
455+
{
456+
name: "docker manifest list",
457+
mediaType: docker.MediaTypeManifestList,
458+
},
459+
{
460+
name: "image index",
461+
mediaType: ocispec.MediaTypeImageIndex,
462+
},
463+
{
464+
name: "artifact manifest",
465+
mediaType: spec.MediaTypeArtifactManifest,
466+
},
467+
}
468+
for _, tt := range tests {
469+
t.Run(tt.name, func(t *testing.T) {
470+
ctx := context.Background()
471+
fetcher := cas.NewMemory()
472+
473+
// prepare test content
474+
data := "invalid json"
475+
desc := ocispec.Descriptor{
476+
MediaType: tt.mediaType,
477+
Digest: digest.FromString(data),
478+
Size: int64(len(data)),
479+
}
480+
if err := fetcher.Push(ctx, desc, bytes.NewReader([]byte(data))); err != nil {
481+
t.Fatalf("failed to push test content to fetcher: %v", err)
482+
}
483+
484+
// test Successors
485+
if _, err := content.Successors(ctx, fetcher, desc); err == nil {
486+
t.Error("Successors() error = nil, wantErr = true")
487+
}
488+
})
489+
}
490+
}

content/limitedstorage_test.go

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/*
2+
Copyright The ORAS Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package content_test
17+
18+
import (
19+
"bytes"
20+
"context"
21+
"errors"
22+
"io"
23+
"reflect"
24+
"testing"
25+
26+
"github.com/opencontainers/go-digest"
27+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
28+
"oras.land/oras-go/v2/content"
29+
"oras.land/oras-go/v2/errdef"
30+
"oras.land/oras-go/v2/internal/cas"
31+
)
32+
33+
func TestLimitedStorage_Push(t *testing.T) {
34+
data := []byte("test")
35+
size := int64(len(data))
36+
dgst := digest.FromBytes(data)
37+
mediaType := "application/vnd.test"
38+
39+
tests := []struct {
40+
name string
41+
desc ocispec.Descriptor
42+
limit int64
43+
wantErr error
44+
}{
45+
{
46+
name: "descriptor size matches actual size and is within limit",
47+
desc: ocispec.Descriptor{
48+
MediaType: mediaType,
49+
Size: size,
50+
Digest: dgst,
51+
},
52+
limit: size,
53+
wantErr: nil,
54+
},
55+
{
56+
name: "descriptor size matches actual size but exeeds limit",
57+
desc: ocispec.Descriptor{
58+
MediaType: mediaType,
59+
Size: size,
60+
Digest: dgst,
61+
},
62+
limit: size - 1,
63+
wantErr: errdef.ErrSizeExceedsLimit,
64+
},
65+
{
66+
name: "descriptor size mismatches actual size and is within limit",
67+
desc: ocispec.Descriptor{
68+
MediaType: mediaType,
69+
Size: size - 1,
70+
Digest: dgst,
71+
},
72+
limit: size,
73+
wantErr: content.ErrMismatchedDigest,
74+
},
75+
{
76+
name: "descriptor size mismatches actual size and exceeds limit",
77+
desc: ocispec.Descriptor{
78+
MediaType: mediaType,
79+
Size: size + 1,
80+
Digest: dgst,
81+
},
82+
limit: size,
83+
wantErr: errdef.ErrSizeExceedsLimit,
84+
},
85+
}
86+
for _, tt := range tests {
87+
t.Run(tt.name, func(t *testing.T) {
88+
ctx := context.Background()
89+
ls := content.LimitStorage(cas.NewMemory(), tt.limit)
90+
91+
// test Push
92+
err := ls.Push(ctx, tt.desc, bytes.NewReader(data))
93+
if err != nil {
94+
if errors.Is(err, tt.wantErr) {
95+
return
96+
}
97+
t.Errorf("LimitedStorage.Push() error = %v, wantErr %v", err, tt.wantErr)
98+
}
99+
100+
// verify
101+
rc, err := ls.Storage.Fetch(ctx, tt.desc)
102+
if err != nil {
103+
t.Fatalf("LimitedStorage.Fetch() error = %v", err)
104+
}
105+
defer rc.Close()
106+
107+
got, err := io.ReadAll(rc)
108+
if err != nil {
109+
t.Fatalf("io.ReadAll() error = %v", err)
110+
}
111+
if !reflect.DeepEqual(got, data) {
112+
t.Errorf("LimitedStorage.Fetch() = %v, want %v", got, data)
113+
}
114+
})
115+
}
116+
}

content/storage_test.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
Copyright The ORAS Authors.
3+
Licensed under the Apache License, Version 2.0 (the "License");
4+
you may not use this file except in compliance with the License.
5+
You may obtain a copy of the License at
6+
7+
http://www.apache.org/licenses/LICENSE-2.0
8+
9+
Unless required by applicable law or agreed to in writing, software
10+
distributed under the License is distributed on an "AS IS" BASIS,
11+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
See the License for the specific language governing permissions and
13+
limitations under the License.
14+
*/
15+
16+
package content
17+
18+
import (
19+
"bytes"
20+
"context"
21+
"errors"
22+
"io"
23+
"testing"
24+
25+
"github.com/opencontainers/go-digest"
26+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
27+
)
28+
29+
func TestFetcherFunc_Fetch(t *testing.T) {
30+
data := []byte("test content")
31+
desc := ocispec.Descriptor{
32+
MediaType: "test",
33+
Digest: digest.FromBytes(data),
34+
Size: int64(len(data)),
35+
}
36+
37+
fetcherFunc := FetcherFunc(func(ctx context.Context, target ocispec.Descriptor) (io.ReadCloser, error) {
38+
if target.Digest != desc.Digest {
39+
return nil, errors.New("content not found")
40+
}
41+
return io.NopCloser(bytes.NewReader(data)), nil
42+
})
43+
44+
ctx := context.Background()
45+
rc, err := fetcherFunc.Fetch(ctx, desc)
46+
if err != nil {
47+
t.Fatalf("FetcherFunc.Fetch() error = %v", err)
48+
}
49+
defer rc.Close()
50+
51+
got, err := io.ReadAll(rc)
52+
if err != nil {
53+
t.Fatalf("FetcherFunc.Fetch().Read() error = %v", err)
54+
}
55+
if !bytes.Equal(got, data) {
56+
t.Errorf("FetcherFunc.Fetch() = %v, want %v", got, data)
57+
}
58+
}

0 commit comments

Comments
 (0)