Skip to content

Commit

Permalink
test: increase unit test coverage to 80% (#876)
Browse files Browse the repository at this point in the history
1. Increase unit test coverage to 80%
2. Set Codecov threshold to 80%

Resolves: #779
Signed-off-by: Lixia (Sylvia) Lei <[email protected]>
  • Loading branch information
Wwwsylvia authored Jan 22, 2025
1 parent dff5628 commit bb3d178
Show file tree
Hide file tree
Showing 13 changed files with 2,022 additions and 305 deletions.
2 changes: 1 addition & 1 deletion .github/.codecov.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ coverage:
status:
project:
default:
target: 75%
target: 80%
if_ci_failed: error
patch:
default:
Expand Down
99 changes: 99 additions & 0 deletions content/graph_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,14 @@ import (
"bytes"
"context"
"encoding/json"
"errors"
"reflect"
"testing"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2/content"
"oras.land/oras-go/v2/errdef"
"oras.land/oras-go/v2/internal/cas"
"oras.land/oras-go/v2/internal/docker"
"oras.land/oras-go/v2/internal/spec"
Expand Down Expand Up @@ -389,3 +391,100 @@ func TestSuccessors_otherMediaType(t *testing.T) {
t.Errorf("Successors() = %v, want nil", got)
}
}

func TestSuccessors_ErrNotFound(t *testing.T) {
tests := []struct {
name string
desc ocispec.Descriptor
}{
{
name: "docker manifest",
desc: ocispec.Descriptor{
MediaType: docker.MediaTypeManifest,
},
},
{
name: "image manifest",
desc: ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageManifest,
},
},
{
name: "docker manifest list",
desc: ocispec.Descriptor{
MediaType: docker.MediaTypeManifestList,
},
},
{
name: "image index",
desc: ocispec.Descriptor{
MediaType: ocispec.MediaTypeImageIndex,
},
},
{
name: "artifact manifest",
desc: ocispec.Descriptor{
MediaType: spec.MediaTypeArtifactManifest,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
fetcher := cas.NewMemory()
if _, err := content.Successors(ctx, fetcher, tt.desc); !errors.Is(err, errdef.ErrNotFound) {
t.Errorf("Successors() error = %v, wantErr = %v", err, errdef.ErrNotFound)
}
})
}
}

func TestSuccessors_UnmarshalError(t *testing.T) {
tests := []struct {
name string
mediaType string
}{
{
name: "docker manifest",
mediaType: docker.MediaTypeManifest,
},
{
name: "image manifest",
mediaType: ocispec.MediaTypeImageManifest,
},
{
name: "docker manifest list",
mediaType: docker.MediaTypeManifestList,
},
{
name: "image index",
mediaType: ocispec.MediaTypeImageIndex,
},
{
name: "artifact manifest",
mediaType: spec.MediaTypeArtifactManifest,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
fetcher := cas.NewMemory()

// prepare test content
data := "invalid json"
desc := ocispec.Descriptor{
MediaType: tt.mediaType,
Digest: digest.FromString(data),
Size: int64(len(data)),
}
if err := fetcher.Push(ctx, desc, bytes.NewReader([]byte(data))); err != nil {
t.Fatalf("failed to push test content to fetcher: %v", err)
}

// test Successors
if _, err := content.Successors(ctx, fetcher, desc); err == nil {
t.Error("Successors() error = nil, wantErr = true")
}
})
}
}
116 changes: 116 additions & 0 deletions content/limitedstorage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package content_test

import (
"bytes"
"context"
"errors"
"io"
"reflect"
"testing"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"oras.land/oras-go/v2/content"
"oras.land/oras-go/v2/errdef"
"oras.land/oras-go/v2/internal/cas"
)

func TestLimitedStorage_Push(t *testing.T) {
data := []byte("test")
size := int64(len(data))
dgst := digest.FromBytes(data)
mediaType := "application/vnd.test"

tests := []struct {
name string
desc ocispec.Descriptor
limit int64
wantErr error
}{
{
name: "descriptor size matches actual size and is within limit",
desc: ocispec.Descriptor{
MediaType: mediaType,
Size: size,
Digest: dgst,
},
limit: size,
wantErr: nil,
},
{
name: "descriptor size matches actual size but exeeds limit",
desc: ocispec.Descriptor{
MediaType: mediaType,
Size: size,
Digest: dgst,
},
limit: size - 1,
wantErr: errdef.ErrSizeExceedsLimit,
},
{
name: "descriptor size mismatches actual size and is within limit",
desc: ocispec.Descriptor{
MediaType: mediaType,
Size: size - 1,
Digest: dgst,
},
limit: size,
wantErr: content.ErrMismatchedDigest,
},
{
name: "descriptor size mismatches actual size and exceeds limit",
desc: ocispec.Descriptor{
MediaType: mediaType,
Size: size + 1,
Digest: dgst,
},
limit: size,
wantErr: errdef.ErrSizeExceedsLimit,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctx := context.Background()
ls := content.LimitStorage(cas.NewMemory(), tt.limit)

// test Push
err := ls.Push(ctx, tt.desc, bytes.NewReader(data))
if err != nil {
if errors.Is(err, tt.wantErr) {
return
}
t.Errorf("LimitedStorage.Push() error = %v, wantErr %v", err, tt.wantErr)
}

// verify
rc, err := ls.Storage.Fetch(ctx, tt.desc)
if err != nil {
t.Fatalf("LimitedStorage.Fetch() error = %v", err)
}
defer rc.Close()

got, err := io.ReadAll(rc)
if err != nil {
t.Fatalf("io.ReadAll() error = %v", err)
}
if !reflect.DeepEqual(got, data) {
t.Errorf("LimitedStorage.Fetch() = %v, want %v", got, data)
}
})
}
}
58 changes: 58 additions & 0 deletions content/storage_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
Copyright The ORAS Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package content

import (
"bytes"
"context"
"errors"
"io"
"testing"

"github.com/opencontainers/go-digest"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
)

func TestFetcherFunc_Fetch(t *testing.T) {
data := []byte("test content")
desc := ocispec.Descriptor{
MediaType: "test",
Digest: digest.FromBytes(data),
Size: int64(len(data)),
}

fetcherFunc := FetcherFunc(func(ctx context.Context, target ocispec.Descriptor) (io.ReadCloser, error) {
if target.Digest != desc.Digest {
return nil, errors.New("content not found")
}
return io.NopCloser(bytes.NewReader(data)), nil
})

ctx := context.Background()
rc, err := fetcherFunc.Fetch(ctx, desc)
if err != nil {
t.Fatalf("FetcherFunc.Fetch() error = %v", err)
}
defer rc.Close()

got, err := io.ReadAll(rc)
if err != nil {
t.Fatalf("FetcherFunc.Fetch().Read() error = %v", err)
}
if !bytes.Equal(got, data) {
t.Errorf("FetcherFunc.Fetch() = %v, want %v", got, data)
}
}
Loading

0 comments on commit bb3d178

Please sign in to comment.