blob: 8fe863762e9f3df862f5ed36c43c6c4f01a6b191 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You 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 manifest_test
import (
"bytes"
"context"
"fmt"
"io"
"strings"
"testing"
"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/manifest"
"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/storage"
"github.com/apache/dubbo-kubernetes/pkg/bufman/pkg/storage/storagemem"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestFromBucket(t *testing.T) {
t.Parallel()
ctx := context.Background()
bucket, err := storagemem.NewReadBucket(
map[string][]byte{
"null": nil,
"foo": []byte("bar"),
})
require.NoError(t, err)
m, blobSet, err := manifest.NewFromBucket(ctx, bucket)
require.NoError(t, err)
// sorted by paths
var (
fooDigest = mustDigestShake256(t, []byte("bar"))
nullDigest = mustDigestShake256(t, nil)
)
expected := fmt.Sprintf("%s foo\n", fooDigest)
expected += fmt.Sprintf("%s null\n", nullDigest)
retContent, err := m.MarshalText()
assert.NoError(t, err)
assert.Equal(t, expected, string(retContent))
// blobs
fooBlob, ok := blobSet.BlobFor(fooDigest.String())
require.True(t, ok)
assert.True(t, fooDigest.Equal(*fooBlob.Digest()))
nullBlob, ok := blobSet.BlobFor(nullDigest.String())
require.True(t, ok)
assert.True(t, nullDigest.Equal(*nullBlob.Digest()))
}
func TestNewBucket(t *testing.T) {
t.Parallel()
files := map[string][]byte{
"some_empty_file": {},
"buf.yaml": []byte("buf yaml contents"),
"buf.lock": []byte("buf lock contents"),
"mypkg/v1/foo.proto": []byte("repeated proto content"),
"mypkg/v1/bar.proto": []byte("repeated proto content"),
// same "mypkg" prefix for `Walk` test purposes
"mypkglongername/v1/baz.proto": []byte("repeated proto content"),
}
var m manifest.Manifest
var blobs []manifest.Blob
digester, err := manifest.NewDigester(manifest.DigestTypeShake256)
require.NoError(t, err)
for path, content := range files {
digest, err := digester.Digest(bytes.NewReader(content))
require.NoError(t, err)
require.NoError(t, m.AddEntry(path, *digest))
blob, err := manifest.NewMemoryBlob(
*digest,
content,
manifest.MemoryBlobWithDigestValidation(),
)
require.NoError(t, err)
blobs = append(blobs, blob)
}
blobSet, err := manifest.NewBlobSet(
context.Background(),
blobs,
manifest.BlobSetWithContentValidation(),
)
require.NoError(t, err)
t.Run("BucketWithAllManifestBlobsValidation", func(t *testing.T) {
t.Parallel()
// only send 3 blobs: there are 6 files with 4 different contents,
// regardless of which blobs are sent, there will always be missing at least
// one.
const blobsToSend = 3
incompleteBlobSet, err := manifest.NewBlobSet(
context.Background(),
blobs[:blobsToSend],
)
require.NoError(t, err)
_, err = manifest.NewBucket(
m, *incompleteBlobSet,
manifest.BucketWithAllManifestBlobsValidation(),
)
assert.Error(t, err)
bucket, err := manifest.NewBucket(m, *incompleteBlobSet)
assert.NoError(t, err)
assert.NotNil(t, bucket)
var bucketFilesCount int
require.NoError(t, bucket.Walk(context.Background(), "", func(obj storage.ObjectInfo) error {
bucketFilesCount++
return nil
}))
assert.Less(t, bucketFilesCount, len(files)) // incomplete bucket
})
t.Run("BucketWithNoExtraBlobsValidation", func(t *testing.T) {
t.Parallel()
const content = "some other file contents"
digest := mustDigestShake256(t, []byte(content))
orphanBlob, err := manifest.NewMemoryBlob(*digest, []byte(content))
require.NoError(t, err)
tooLargeBlobSet, err := manifest.NewBlobSet(
context.Background(),
append(blobs, orphanBlob),
)
require.NoError(t, err)
_, err = manifest.NewBucket(
m, *tooLargeBlobSet,
manifest.BucketWithNoExtraBlobsValidation(),
)
assert.Error(t, err)
})
t.Run("Valid", func(t *testing.T) {
t.Parallel()
bucket, err := manifest.NewBucket(
m, *blobSet,
manifest.BucketWithAllManifestBlobsValidation(),
manifest.BucketWithNoExtraBlobsValidation(),
)
require.NoError(t, err)
t.Run("BucketGet", func(t *testing.T) {
t.Parallel()
// make sure all files are present and have the right content
for path, content := range files {
obj, err := bucket.Get(context.Background(), path)
require.NoError(t, err)
retContent, err := io.ReadAll(obj)
require.NoError(t, err)
assert.Equal(t, content, retContent)
assert.NoError(t, obj.Close())
}
// non existent files
_, err = bucket.Get(context.Background(), "path/not/present")
assert.Error(t, err)
})
t.Run("BucketWalk", func(t *testing.T) {
t.Parallel()
// make sure there are no extra files in the bucket
require.NoError(t, bucket.Walk(context.Background(), "", func(obj storage.ObjectInfo) error {
_, presentInOriginalFiles := files[obj.Path()]
require.True(t, presentInOriginalFiles, "path %q in bucket is not present in original files", obj.Path())
return nil
}))
// walking a non existent dir
assert.NoError(t, bucket.Walk(context.Background(), "nonexistentpkg", func(obj storage.ObjectInfo) error {
require.Fail(t, "unexpected file %q in the bucket", obj.Path())
return nil
}))
// walking a valid dir
const prefix = "mypkg"
expectedPaths := make(map[string]struct{}, 0)
for path := range files {
if strings.HasPrefix(path, prefix+"/") {
expectedPaths[path] = struct{}{}
}
}
assert.NoError(t, bucket.Walk(context.Background(), prefix, func(obj storage.ObjectInfo) error {
_, expected := expectedPaths[obj.Path()]
require.True(t, expected, "walking path %q was not expected", obj.Path())
return nil
}))
})
})
}
func TestToBucketEmpty(t *testing.T) {
t.Parallel()
var m manifest.Manifest
bucket, err := manifest.NewBucket(m, manifest.BlobSet{})
require.NoError(t, err)
// make sure there are no files in the bucket
require.NoError(t, bucket.Walk(context.Background(), "", func(obj storage.ObjectInfo) error {
require.Fail(t, "unexpected file %q in the bucket", obj.Path())
return nil
}))
}