Skip to content

Commit 43b5acf

Browse files
committed
ci(ut): add ut for test coverage
Signed-off-by: imeoer <yansong.ys@antgroup.com>
1 parent 821a512 commit 43b5acf

30 files changed

Lines changed: 2447 additions & 60 deletions
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package backend
2+
3+
import (
4+
"context"
5+
"io"
6+
"os"
7+
"reflect"
8+
"testing"
9+
10+
"github.com/agiledragon/gomonkey/v2"
11+
"github.com/opencontainers/go-digest"
12+
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
13+
"github.com/stretchr/testify/require"
14+
15+
"github.com/dragonflyoss/nydus/contrib/nydusify/pkg/remote"
16+
"github.com/dragonflyoss/nydus/contrib/nydusify/pkg/utils"
17+
)
18+
19+
func TestRegistryUpload(t *testing.T) {
20+
tmp, err := os.CreateTemp(t.TempDir(), "blob-*")
21+
require.NoError(t, err)
22+
_, err = tmp.WriteString("blob-data")
23+
require.NoError(t, err)
24+
require.NoError(t, tmp.Close())
25+
26+
registry := &Registry{remote: &remote.Remote{}}
27+
patches := gomonkey.ApplyMethod(reflect.TypeOf(&remote.Remote{}), "Push", func(_ *remote.Remote, _ context.Context, desc ocispec.Descriptor, byDigest bool, reader io.Reader) error {
28+
require.True(t, byDigest)
29+
require.Equal(t, utils.MediaTypeNydusBlob, desc.MediaType)
30+
require.Equal(t, digest.Digest("sha256:205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a"), desc.Digest)
31+
content, err := io.ReadAll(reader)
32+
require.NoError(t, err)
33+
require.Equal(t, "blob-data", string(content))
34+
return nil
35+
})
36+
defer patches.Reset()
37+
38+
desc, err := registry.Upload(context.Background(), "205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a", tmp.Name(), 8, false)
39+
require.NoError(t, err)
40+
require.Equal(t, int64(8), desc.Size)
41+
require.Equal(t, utils.MediaTypeNydusBlob, desc.MediaType)
42+
assertAnnotations := map[string]string{
43+
utils.LayerAnnotationUncompressed: "sha256:205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a",
44+
utils.LayerAnnotationNydusBlob: "true",
45+
}
46+
require.Equal(t, assertAnnotations, desc.Annotations)
47+
}
48+
49+
func TestRegistryUploadFailuresAndHelpers(t *testing.T) {
50+
registry := &Registry{remote: &remote.Remote{}}
51+
52+
_, err := registry.Upload(context.Background(), "205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a", "/non-existent", 1, false)
53+
require.ErrorContains(t, err, "Open blob file")
54+
55+
tmp, err := os.CreateTemp(t.TempDir(), "blob-*")
56+
require.NoError(t, err)
57+
require.NoError(t, tmp.Close())
58+
59+
patches := gomonkey.ApplyMethod(reflect.TypeOf(&remote.Remote{}), "Push", func(_ *remote.Remote, _ context.Context, _ ocispec.Descriptor, _ bool, _ io.Reader) error {
60+
return io.EOF
61+
})
62+
defer patches.Reset()
63+
64+
_, err = registry.Upload(context.Background(), "205eed24cbec29ad9cb4593a73168ef1803402370a82f7d51ce25646fc2f943a", tmp.Name(), 0, false)
65+
require.ErrorContains(t, err, "Push blob layer")
66+
67+
require.NoError(t, registry.Finalize(false))
68+
ok, err := registry.Check("ignored")
69+
require.NoError(t, err)
70+
require.True(t, ok)
71+
require.Equal(t, RegistryBackend, registry.Type())
72+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
// Copyright 2026 Nydus Developers. All rights reserved.
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package build
6+
7+
import (
8+
"bytes"
9+
"os"
10+
"path/filepath"
11+
"strings"
12+
"testing"
13+
14+
"github.com/stretchr/testify/require"
15+
)
16+
17+
func createFakeBinary(t *testing.T) (string, string, string) {
18+
t.Helper()
19+
20+
tempDir := t.TempDir()
21+
argsPath := filepath.Join(tempDir, "args.txt")
22+
stdinPath := filepath.Join(tempDir, "stdin.txt")
23+
binaryPath := filepath.Join(tempDir, "fake-nydus-image.sh")
24+
25+
script := "#!/bin/sh\n" +
26+
"printf '%s\\n' \"$@\" > \"$NYDUS_ARGS_FILE\"\n" +
27+
"cat > \"$NYDUS_STDIN_FILE\"\n"
28+
29+
require.NoError(t, os.WriteFile(binaryPath, []byte(script), 0o755))
30+
t.Setenv("NYDUS_ARGS_FILE", argsPath)
31+
t.Setenv("NYDUS_STDIN_FILE", stdinPath)
32+
33+
return binaryPath, argsPath, stdinPath
34+
}
35+
36+
func readLines(t *testing.T, path string) []string {
37+
t.Helper()
38+
39+
content, err := os.ReadFile(path)
40+
require.NoError(t, err)
41+
text := strings.TrimSpace(string(content))
42+
if text == "" {
43+
return nil
44+
}
45+
46+
return strings.Split(text, "\n")
47+
}
48+
49+
func TestNewBuilderUsesStdStreams(t *testing.T) {
50+
builder := NewBuilder("/usr/bin/nydus-image")
51+
require.Equal(t, "/usr/bin/nydus-image", builder.binaryPath)
52+
require.Equal(t, os.Stdout, builder.stdout)
53+
require.Equal(t, os.Stderr, builder.stderr)
54+
}
55+
56+
func TestBuilderRunBuildCommand(t *testing.T) {
57+
binaryPath, argsPath, stdinPath := createFakeBinary(t)
58+
builder := NewBuilder(binaryPath)
59+
builder.stdout = &bytes.Buffer{}
60+
builder.stderr = &bytes.Buffer{}
61+
62+
err := builder.Run(BuilderOption{
63+
ParentBootstrapPath: "/tmp/parent.boot",
64+
ChunkDict: "/tmp/chunk.dict",
65+
BootstrapPath: "/tmp/bootstrap.boot",
66+
RootfsPath: "/tmp/rootfs",
67+
WhiteoutSpec: "overlayfs",
68+
OutputJSONPath: "/tmp/output.json",
69+
PrefetchPatterns: "/etc\n/usr/bin",
70+
BlobPath: "/tmp/blob.data",
71+
AlignedChunk: true,
72+
Compressor: "zstd",
73+
ChunkSize: "0x200000",
74+
FsVersion: "6",
75+
})
76+
require.NoError(t, err)
77+
78+
require.Equal(t, []string{
79+
"create",
80+
"--parent-bootstrap",
81+
"/tmp/parent.boot",
82+
"--aligned-chunk",
83+
"--chunk-dict",
84+
"/tmp/chunk.dict",
85+
"--bootstrap",
86+
"/tmp/bootstrap.boot",
87+
"--log-level",
88+
"warn",
89+
"--whiteout-spec",
90+
"overlayfs",
91+
"--output-json",
92+
"/tmp/output.json",
93+
"--blob",
94+
"/tmp/blob.data",
95+
"--fs-version",
96+
"6",
97+
"--compressor",
98+
"zstd",
99+
"--prefetch-policy",
100+
"fs",
101+
"--chunk-size",
102+
"0x200000",
103+
"/tmp/rootfs",
104+
}, readLines(t, argsPath))
105+
106+
stdinContent, err := os.ReadFile(stdinPath)
107+
require.NoError(t, err)
108+
require.Equal(t, "/etc\n/usr/bin", string(stdinContent))
109+
}
110+
111+
func TestBuilderCompactAndGenerateCommands(t *testing.T) {
112+
binaryPath, argsPath, stdinPath := createFakeBinary(t)
113+
builder := NewBuilder(binaryPath)
114+
builder.stdout = &bytes.Buffer{}
115+
builder.stderr = &bytes.Buffer{}
116+
117+
err := builder.Compact(CompactOption{
118+
ChunkDict: "/tmp/chunk.dict",
119+
BootstrapPath: "/tmp/bootstrap.boot",
120+
OutputBootstrapPath: "/tmp/output.boot",
121+
BackendType: "oss",
122+
BackendConfigPath: "/tmp/backend.json",
123+
OutputJSONPath: "/tmp/output.json",
124+
MinUsedRatio: "30",
125+
CompactBlobSize: "1048576",
126+
MaxCompactSize: "2097152",
127+
LayersToCompact: "2",
128+
BlobsDir: "/tmp/blobs",
129+
})
130+
require.NoError(t, err)
131+
require.Equal(t, []string{
132+
"compact",
133+
"--bootstrap",
134+
"/tmp/bootstrap.boot",
135+
"--blob-dir",
136+
"/tmp/blobs",
137+
"--min-used-ratio",
138+
"30",
139+
"--compact-blob-size",
140+
"1048576",
141+
"--max-compact-size",
142+
"2097152",
143+
"--layers-to-compact",
144+
"2",
145+
"--backend-type",
146+
"oss",
147+
"--backend-config-file",
148+
"/tmp/backend.json",
149+
"--log-level",
150+
"info",
151+
"--output-json",
152+
"/tmp/output.json",
153+
"--output-bootstrap",
154+
"/tmp/output.boot",
155+
"--chunk-dict",
156+
"/tmp/chunk.dict",
157+
}, readLines(t, argsPath))
158+
require.Empty(t, readLines(t, stdinPath))
159+
160+
err = builder.Generate(GenerateOption{
161+
BootstrapPaths: []string{"/tmp/layer1.boot", "/tmp/layer2.boot"},
162+
DatabasePath: "/tmp/chunk.db",
163+
ChunkdictBootstrapPath: "/tmp/chunkdict.boot",
164+
OutputPath: "/tmp/chunkdict.json",
165+
})
166+
require.NoError(t, err)
167+
require.Equal(t, []string{
168+
"chunkdict",
169+
"generate",
170+
"--log-level",
171+
"warn",
172+
"--bootstrap",
173+
"/tmp/chunkdict.boot",
174+
"--database",
175+
"/tmp/chunk.db",
176+
"--output-json",
177+
"/tmp/chunkdict.json",
178+
"/tmp/layer1.boot",
179+
"/tmp/layer2.boot",
180+
}, readLines(t, argsPath))
181+
}

0 commit comments

Comments
 (0)