mirror of
https://github.com/goreleaser/nfpm
synced 2024-11-18 23:14:12 +01:00
437d9ef31a
* refactor: remove usage of ioutil Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> * fix(ci): actually use go 1.19 Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com> Signed-off-by: Carlos A Becker <caarlos0@users.noreply.github.com>
721 lines
17 KiB
Go
721 lines
17 KiB
Go
package apk
|
|
|
|
import (
|
|
"archive/tar"
|
|
"bytes"
|
|
"compress/gzip"
|
|
"crypto/sha1" // nolint:gosec
|
|
"crypto/sha256"
|
|
"errors"
|
|
"flag"
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/goreleaser/nfpm/v2"
|
|
"github.com/goreleaser/nfpm/v2/files"
|
|
"github.com/goreleaser/nfpm/v2/internal/sign"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// nolint: gochecknoglobals
|
|
var update = flag.Bool("update", false, "update apk .golden files")
|
|
|
|
func exampleInfo() *nfpm.Info {
|
|
return nfpm.WithDefaults(&nfpm.Info{
|
|
Name: "foo",
|
|
Arch: "amd64",
|
|
Description: "Foo does things",
|
|
Priority: "extra",
|
|
Maintainer: "Carlos A Becker <pkg@carlosbecker.com>",
|
|
Version: "v1.0.0",
|
|
Prerelease: "beta1",
|
|
Release: "r1",
|
|
Section: "default",
|
|
Homepage: "http://carlosbecker.com",
|
|
Vendor: "nope",
|
|
Overridables: nfpm.Overridables{
|
|
Depends: []string{
|
|
"bash",
|
|
"foo",
|
|
},
|
|
Recommends: []string{
|
|
"git",
|
|
"bar",
|
|
},
|
|
Suggests: []string{
|
|
"bash",
|
|
"lala",
|
|
},
|
|
Replaces: []string{
|
|
"svn",
|
|
"subversion",
|
|
},
|
|
Provides: []string{
|
|
"bzr",
|
|
"zzz",
|
|
},
|
|
Conflicts: []string{
|
|
"zsh",
|
|
"foobarsh",
|
|
},
|
|
Contents: []*files.Content{
|
|
{
|
|
Source: "../testdata/fake",
|
|
Destination: "/usr/local/bin/fake",
|
|
},
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/usr/share/doc/fake/fake.txt",
|
|
},
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/etc/fake/fake.conf",
|
|
Type: "config",
|
|
},
|
|
{
|
|
Destination: "/var/log/whatever",
|
|
Type: "dir",
|
|
},
|
|
{
|
|
Destination: "/usr/share/whatever",
|
|
Type: "dir",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
func TestCreateBuilderData(t *testing.T) {
|
|
info := exampleInfo()
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
size := int64(0)
|
|
builderData := createBuilderData(info, &size)
|
|
|
|
var buf bytes.Buffer
|
|
tw := tar.NewWriter(&buf)
|
|
|
|
require.NoError(t, builderData(tw))
|
|
|
|
require.Equal(t, 11784, buf.Len())
|
|
}
|
|
|
|
func TestCombineToApk(t *testing.T) {
|
|
var bufData bytes.Buffer
|
|
bufData.Write([]byte{1})
|
|
|
|
var bufControl bytes.Buffer
|
|
bufControl.Write([]byte{2})
|
|
|
|
var bufTarget bytes.Buffer
|
|
|
|
require.NoError(t, combineToApk(&bufTarget, &bufData, &bufControl))
|
|
require.Equal(t, 2, bufTarget.Len())
|
|
}
|
|
|
|
func TestPathsToCreate(t *testing.T) {
|
|
for pathToTest, parts := range map[string][]string{
|
|
"/usr/share/doc/whatever/foo.md": {"usr", "usr/share", "usr/share/doc", "usr/share/doc/whatever"},
|
|
"/var/moises": {"var"},
|
|
"/": {},
|
|
} {
|
|
parts := parts
|
|
pathToTest := pathToTest
|
|
t.Run(fmt.Sprintf("pathToTest: '%s'", pathToTest), func(t *testing.T) {
|
|
require.Equal(t, parts, pathsToCreate(pathToTest))
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDefaultWithArch(t *testing.T) {
|
|
expectedChecksums := map[string]string{
|
|
"usr/share/doc/fake/fake.txt": "96c335dc28122b5f09a4cef74b156cd24c23784c",
|
|
"usr/local/bin/fake": "f46cece3eeb7d9ed5cb244d902775427be71492d",
|
|
"etc/fake/fake.conf": "96c335dc28122b5f09a4cef74b156cd24c23784c",
|
|
}
|
|
for _, arch := range []string{"386", "amd64"} {
|
|
arch := arch
|
|
t.Run(arch, func(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Arch = arch
|
|
|
|
var f bytes.Buffer
|
|
require.NoError(t, Default.Package(info, &f))
|
|
|
|
gz, err := gzip.NewReader(&f)
|
|
require.NoError(t, err)
|
|
defer gz.Close()
|
|
tr := tar.NewReader(gz)
|
|
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break // End of archive
|
|
}
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, expectedChecksums[hdr.Name], hdr.PAXRecords["APK-TOOLS.checksum.SHA1"], hdr.Name)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestNoInfo(t *testing.T) {
|
|
err := Default.Package(nfpm.WithDefaults(&nfpm.Info{}), io.Discard)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestFileDoesNotExist(t *testing.T) {
|
|
abs, err := filepath.Abs("../testdata/whatever.confzzz")
|
|
require.NoError(t, err)
|
|
err = Default.Package(
|
|
nfpm.WithDefaults(&nfpm.Info{
|
|
Name: "foo",
|
|
Arch: "amd64",
|
|
Description: "Foo does things",
|
|
Priority: "extra",
|
|
Maintainer: "Carlos A Becker <pkg@carlosbecker.com>",
|
|
Version: "1.0.0",
|
|
Section: "default",
|
|
Homepage: "http://carlosbecker.com",
|
|
Vendor: "nope",
|
|
Overridables: nfpm.Overridables{
|
|
Depends: []string{
|
|
"bash",
|
|
},
|
|
Contents: []*files.Content{
|
|
{
|
|
Source: "../testdata/fake",
|
|
Destination: "/usr/local/bin/fake",
|
|
},
|
|
{
|
|
Source: "../testdata/whatever.confzzz",
|
|
Destination: "/etc/fake/fake.conf",
|
|
Type: "config",
|
|
},
|
|
},
|
|
},
|
|
}),
|
|
io.Discard,
|
|
)
|
|
require.EqualError(t, err, fmt.Sprintf("matching \"%s\": file does not exist", filepath.ToSlash(abs)))
|
|
}
|
|
|
|
func TestNoFiles(t *testing.T) {
|
|
err := Default.Package(
|
|
nfpm.WithDefaults(&nfpm.Info{
|
|
Name: "foo",
|
|
Arch: "amd64",
|
|
Description: "Foo does things",
|
|
Priority: "extra",
|
|
Maintainer: "Carlos A Becker <pkg@carlosbecker.com>",
|
|
Version: "1.0.0",
|
|
Section: "default",
|
|
Homepage: "http://carlosbecker.com",
|
|
Vendor: "nope",
|
|
Overridables: nfpm.Overridables{
|
|
Depends: []string{
|
|
"bash",
|
|
},
|
|
},
|
|
}),
|
|
io.Discard,
|
|
)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestCreateBuilderControl(t *testing.T) {
|
|
info := exampleInfo()
|
|
size := int64(12345)
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
builderControl := createBuilderControl(info, size, sha256.New().Sum(nil))
|
|
|
|
var w bytes.Buffer
|
|
tw := tar.NewWriter(&w)
|
|
require.NoError(t, builderControl(tw))
|
|
|
|
control := string(extractFromTar(t, w.Bytes(), ".PKGINFO"))
|
|
golden := "testdata/TestCreateBuilderControl.golden"
|
|
if *update {
|
|
require.NoError(t, os.WriteFile(golden, []byte(control), 0o655)) // nolint: gosec
|
|
}
|
|
bts, err := os.ReadFile(golden) //nolint:gosec
|
|
require.NoError(t, err)
|
|
require.Equal(t, string(bts), control)
|
|
}
|
|
|
|
func TestCreateBuilderControlScripts(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Scripts = nfpm.Scripts{
|
|
PreInstall: "../testdata/scripts/preinstall.sh",
|
|
PostInstall: "../testdata/scripts/postinstall.sh",
|
|
PreRemove: "../testdata/scripts/preremove.sh",
|
|
PostRemove: "../testdata/scripts/postremove.sh",
|
|
}
|
|
info.APK.Scripts = nfpm.APKScripts{
|
|
PreUpgrade: "../testdata/scripts/preupgrade.sh",
|
|
PostUpgrade: "../testdata/scripts/postupgrade.sh",
|
|
}
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
|
|
size := int64(12345)
|
|
builderControl := createBuilderControl(info, size, sha256.New().Sum(nil))
|
|
|
|
var w bytes.Buffer
|
|
tw := tar.NewWriter(&w)
|
|
require.NoError(t, builderControl(tw))
|
|
|
|
control := string(extractFromTar(t, w.Bytes(), ".PKGINFO"))
|
|
golden := "testdata/TestCreateBuilderControlScripts.golden"
|
|
if *update {
|
|
require.NoError(t, os.WriteFile(golden, []byte(control), 0o655)) // nolint: gosec
|
|
}
|
|
bts, err := os.ReadFile(golden) //nolint:gosec
|
|
require.NoError(t, err)
|
|
require.Equal(t, string(bts), control)
|
|
|
|
// Validate scripts are correct
|
|
script := string(extractFromTar(t, w.Bytes(), ".pre-install"))
|
|
require.Contains(t, script, `echo "Preinstall" > /dev/null`)
|
|
script = string(extractFromTar(t, w.Bytes(), ".post-install"))
|
|
require.Contains(t, script, `echo "Postinstall" > /dev/null`)
|
|
script = string(extractFromTar(t, w.Bytes(), ".pre-upgrade"))
|
|
require.Contains(t, script, `echo "PreUpgrade" > /dev/null`)
|
|
script = string(extractFromTar(t, w.Bytes(), ".post-upgrade"))
|
|
require.Contains(t, script, `echo "PostUpgrade" > /dev/null`)
|
|
script = string(extractFromTar(t, w.Bytes(), ".pre-deinstall"))
|
|
require.Contains(t, script, `echo "Preremove" > /dev/null`)
|
|
script = string(extractFromTar(t, w.Bytes(), ".post-deinstall"))
|
|
require.Contains(t, script, `echo "Postremove" > /dev/null`)
|
|
}
|
|
|
|
func TestControl(t *testing.T) {
|
|
var w bytes.Buffer
|
|
require.NoError(t, writeControl(&w, controlData{
|
|
Info: exampleInfo(),
|
|
InstalledSize: 10,
|
|
}))
|
|
golden := "testdata/TestControl.golden"
|
|
if *update {
|
|
require.NoError(t, os.WriteFile(golden, w.Bytes(), 0o655)) // nolint: gosec
|
|
}
|
|
bts, err := os.ReadFile(golden) //nolint:gosec
|
|
require.NoError(t, err)
|
|
require.Equal(t, string(bts), w.String())
|
|
}
|
|
|
|
func TestSignature(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.APK.Signature.KeyFile = "../internal/sign/testdata/rsa.priv"
|
|
info.APK.Signature.KeyName = "testkey.rsa.pub"
|
|
info.APK.Signature.KeyPassphrase = "hunter2"
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
|
|
digest := sha1.New().Sum(nil) // nolint:gosec
|
|
|
|
var signatureTarGz bytes.Buffer
|
|
tw := tar.NewWriter(&signatureTarGz)
|
|
require.NoError(t, createSignatureBuilder(digest, info)(tw))
|
|
|
|
signature := extractFromTar(t, signatureTarGz.Bytes(), ".SIGN.RSA.testkey.rsa.pub")
|
|
err = sign.RSAVerifySHA1Digest(digest, signature, "../internal/sign/testdata/rsa.pub")
|
|
require.NoError(t, err)
|
|
|
|
err = Default.Package(info, io.Discard)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
func TestSignatureError(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.APK.Signature.KeyFile = "../internal/sign/testdata/rsa.priv"
|
|
info.APK.Signature.KeyName = "testkey.rsa.pub"
|
|
info.APK.Signature.KeyPassphrase = "hunter2"
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
|
|
// wrong hash format
|
|
digest := sha256.New().Sum(nil)
|
|
|
|
var signatureTarGz bytes.Buffer
|
|
|
|
err = createSignature(&signatureTarGz, info, digest)
|
|
require.Error(t, err)
|
|
|
|
var expectedError *nfpm.ErrSigningFailure
|
|
require.True(t, errors.As(err, &expectedError))
|
|
|
|
info.APK.Signature.KeyName = ""
|
|
info.Maintainer = ""
|
|
digest = sha1.New().Sum(nil) // nolint:gosec
|
|
err = createSignature(&signatureTarGz, info, digest)
|
|
require.True(t, errors.As(err, &expectedError))
|
|
}
|
|
|
|
func TestDisableGlobbing(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.DisableGlobbing = true
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Source: "../testdata/{file}[",
|
|
Destination: "/test/{file}[",
|
|
},
|
|
}
|
|
err := info.Validate()
|
|
require.NoError(t, err)
|
|
|
|
size := int64(0)
|
|
var dataTarGz bytes.Buffer
|
|
_, err = createData(&dataTarGz, info, &size)
|
|
require.NoError(t, err)
|
|
|
|
gzr, err := gzip.NewReader(&dataTarGz)
|
|
require.NoError(t, err)
|
|
dataTar, err := io.ReadAll(gzr)
|
|
require.NoError(t, err)
|
|
|
|
extractedContent := extractFromTar(t, dataTar, "test/{file}[")
|
|
actualContent, err := os.ReadFile("../testdata/{file}[")
|
|
require.NoError(t, err)
|
|
require.Equal(t, actualContent, extractedContent)
|
|
}
|
|
|
|
func extractFromTar(t *testing.T, tarFile []byte, fileName string) []byte {
|
|
t.Helper()
|
|
|
|
tr := tar.NewReader(bytes.NewReader(tarFile))
|
|
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break
|
|
}
|
|
require.NoError(t, err)
|
|
|
|
if hdr.Name != fileName {
|
|
continue
|
|
}
|
|
|
|
data, err := io.ReadAll(tr)
|
|
require.NoError(t, err)
|
|
return data
|
|
}
|
|
|
|
t.Fatalf("file %q not found in tar file", fileName)
|
|
return nil
|
|
}
|
|
|
|
func tarContents(tb testing.TB, tarFile []byte) []string {
|
|
tb.Helper()
|
|
|
|
contents := []string{}
|
|
|
|
tr := tar.NewReader(bytes.NewReader(tarFile))
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break // End of archive
|
|
}
|
|
require.NoError(tb, err)
|
|
|
|
contents = append(contents, hdr.Name)
|
|
}
|
|
|
|
return contents
|
|
}
|
|
|
|
func TestAPKConventionalFileName(t *testing.T) {
|
|
apkName := "default"
|
|
testCases := []struct {
|
|
Arch string
|
|
Version string
|
|
Meta string
|
|
Release string
|
|
Prerelease string
|
|
Expect string
|
|
}{
|
|
{
|
|
Arch: "amd64", Version: "1.2.3",
|
|
Expect: "default_1.2.3_x86_64.apk",
|
|
},
|
|
{
|
|
Arch: "386", Version: "1.2.3", Prerelease: "git",
|
|
Expect: "default_1.2.3git_x86.apk",
|
|
},
|
|
{
|
|
Arch: "386", Version: "1.2.3", Prerelease: "git", Release: "1",
|
|
Expect: "default_1.2.3git-1_x86.apk",
|
|
},
|
|
{
|
|
Arch: "all", Version: "1.2.3",
|
|
Expect: "default_1.2.3_all.apk",
|
|
},
|
|
{
|
|
Arch: "386", Version: "1.2.3", Release: "1", Prerelease: "beta",
|
|
Expect: "default_1.2.3beta-1_x86.apk",
|
|
},
|
|
}
|
|
|
|
for _, testCase := range testCases {
|
|
info := &nfpm.Info{
|
|
Name: apkName,
|
|
Arch: testCase.Arch,
|
|
Version: testCase.Version,
|
|
VersionMetadata: testCase.Meta,
|
|
Release: testCase.Release,
|
|
Prerelease: testCase.Prerelease,
|
|
}
|
|
require.Equal(t, testCase.Expect, Default.ConventionalFileName(info))
|
|
}
|
|
}
|
|
|
|
func TestPackageSymlinks(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Source: "../testdata/fake",
|
|
Destination: "fake",
|
|
Type: "symlink",
|
|
},
|
|
}
|
|
require.NoError(t, Default.Package(info, io.Discard))
|
|
}
|
|
|
|
func TestDirectories(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/etc/foo/file",
|
|
},
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/etc/bar/file",
|
|
},
|
|
{
|
|
Destination: "/etc/bar",
|
|
Type: "dir",
|
|
FileInfo: &files.ContentFileInfo{
|
|
Owner: "test",
|
|
Mode: 0o700,
|
|
},
|
|
},
|
|
{
|
|
Destination: "/etc/baz",
|
|
Type: "dir",
|
|
},
|
|
{
|
|
Destination: "/usr/lib/something/somethingelse",
|
|
Type: "dir",
|
|
},
|
|
}
|
|
|
|
require.NoError(t, info.Validate())
|
|
|
|
var buf bytes.Buffer
|
|
size := int64(0)
|
|
err := createFilesInsideTarGz(info, tar.NewWriter(&buf), make(map[string]bool), &size)
|
|
require.NoError(t, err)
|
|
|
|
require.Equal(t, []string{
|
|
"etc/",
|
|
"etc/bar/",
|
|
"etc/baz/",
|
|
"usr/",
|
|
"usr/lib/",
|
|
"usr/lib/something/",
|
|
"usr/lib/something/somethingelse/",
|
|
"etc/bar/file",
|
|
"etc/foo/",
|
|
"etc/foo/file",
|
|
}, getTree(t, buf.Bytes()))
|
|
|
|
// for apks all implicit or explicit directories are created in the tarball
|
|
h := extractFileHeaderFromTar(t, buf.Bytes(), "/etc")
|
|
require.Equal(t, h.Typeflag, byte(tar.TypeDir))
|
|
h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/foo")
|
|
require.Equal(t, h.Typeflag, byte(tar.TypeDir))
|
|
h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/bar")
|
|
require.Equal(t, h.Typeflag, byte(tar.TypeDir))
|
|
require.Equal(t, h.Mode, int64(0o700))
|
|
require.Equal(t, h.Uname, "test")
|
|
h = extractFileHeaderFromTar(t, buf.Bytes(), "/etc/baz")
|
|
require.Equal(t, h.Typeflag, byte(tar.TypeDir))
|
|
}
|
|
|
|
func TestNoDuplicateAutocreatedDirectories(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.DisableGlobbing = true
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Source: "../testdata/fake",
|
|
Destination: "/etc/foo/bar",
|
|
},
|
|
{
|
|
Type: "dir",
|
|
Destination: "/etc/foo",
|
|
},
|
|
}
|
|
require.NoError(t, info.Validate())
|
|
|
|
expected := map[string]bool{
|
|
"etc/": true,
|
|
"etc/foo/": true,
|
|
"etc/foo/bar": true,
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
size := int64(0)
|
|
err := createFilesInsideTarGz(info, tar.NewWriter(&buf), make(map[string]bool), &size)
|
|
require.NoError(t, err)
|
|
|
|
contents := tarContents(t, buf.Bytes())
|
|
|
|
if len(expected) != len(contents) {
|
|
t.Fatalf("contents has %d entries instead of %d: %#v", len(contents), len(expected), contents)
|
|
}
|
|
|
|
for _, entry := range contents {
|
|
if !expected[entry] {
|
|
t.Fatalf("unexpected content: %q", entry)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestNoDuplicateDirectories(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.DisableGlobbing = true
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Type: "dir",
|
|
Destination: "/etc/foo",
|
|
},
|
|
{
|
|
Type: "dir",
|
|
Destination: "/etc/foo/",
|
|
},
|
|
}
|
|
require.NoError(t, info.Validate())
|
|
|
|
var buf bytes.Buffer
|
|
size := int64(0)
|
|
err := createFilesInsideTarGz(info, tar.NewWriter(&buf), make(map[string]bool), &size)
|
|
require.Error(t, err)
|
|
}
|
|
|
|
func TestNoDuplicateContents(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Contents = []*files.Content{
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/etc/foo/file",
|
|
},
|
|
{
|
|
Source: "../testdata/whatever.conf",
|
|
Destination: "/etc/bar/file",
|
|
},
|
|
{
|
|
Destination: "/etc/bar",
|
|
Type: "dir",
|
|
FileInfo: &files.ContentFileInfo{
|
|
Owner: "test",
|
|
Mode: 0o700,
|
|
},
|
|
},
|
|
{
|
|
Destination: "/etc/baz",
|
|
Type: "dir",
|
|
},
|
|
}
|
|
|
|
require.NoError(t, info.Validate())
|
|
|
|
var buf bytes.Buffer
|
|
size := int64(0)
|
|
err := createFilesInsideTarGz(info, tar.NewWriter(&buf), make(map[string]bool), &size)
|
|
require.NoError(t, err)
|
|
|
|
exists := map[string]bool{}
|
|
|
|
tr := tar.NewReader(bytes.NewReader(buf.Bytes()))
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break // End of archive
|
|
}
|
|
require.NoError(t, err)
|
|
|
|
_, ok := exists[hdr.Name]
|
|
if ok {
|
|
t.Fatalf("%s exists more than once in tarball", hdr.Name)
|
|
}
|
|
|
|
exists[hdr.Name] = true
|
|
}
|
|
}
|
|
|
|
func extractFileHeaderFromTar(tb testing.TB, tarFile []byte, filename string) *tar.Header {
|
|
tb.Helper()
|
|
|
|
tr := tar.NewReader(bytes.NewReader(tarFile))
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break // End of archive
|
|
}
|
|
require.NoError(tb, err)
|
|
|
|
if path.Join("/", hdr.Name) != path.Join("/", filename) { // nolint:gosec
|
|
continue
|
|
}
|
|
|
|
return hdr
|
|
}
|
|
|
|
tb.Fatalf("file %q does not exist in tar", filename)
|
|
|
|
return nil
|
|
}
|
|
|
|
func getTree(tb testing.TB, tarFile []byte) []string {
|
|
tb.Helper()
|
|
|
|
var result []string
|
|
tr := tar.NewReader(bytes.NewReader(tarFile))
|
|
for {
|
|
hdr, err := tr.Next()
|
|
if errors.Is(err, io.EOF) {
|
|
break // End of archive
|
|
}
|
|
require.NoError(tb, err)
|
|
|
|
result = append(result, hdr.Name)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
func TestArches(t *testing.T) {
|
|
for k := range archToAlpine {
|
|
t.Run(k, func(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.Arch = k
|
|
info = ensureValidArch(info)
|
|
require.Equal(t, archToAlpine[k], info.Arch)
|
|
})
|
|
}
|
|
|
|
t.Run("override", func(t *testing.T) {
|
|
info := exampleInfo()
|
|
info.APK.Arch = "foo64"
|
|
info = ensureValidArch(info)
|
|
require.Equal(t, "foo64", info.Arch)
|
|
})
|
|
}
|