jx/internal/resource/package_test.go
Matthew Rich 8feb7b8d56
Some checks failed
Lint / golangci-lint (push) Failing after 10m1s
Declarative Tests / test (push) Failing after 14s
add support of import search paths [doublejynx/jx#7]
2024-10-16 10:26:42 -07:00

460 lines
22 KiB
Go

// Copyright 2024 Matthew Rich <matthewrich.conf@gmail.com>. All rights reserved
package resource
import (
"context"
"fmt"
"github.com/stretchr/testify/assert"
"log/slog"
"testing"
"decl/internal/command"
"decl/internal/folio"
)
func TestNewPackageResource(t *testing.T) {
p := NewPackage()
assert.NotNil(t, p)
}
func TestPackageApplyResourceTransformation(t *testing.T) {
p := NewPackage()
assert.NotNil(t, p)
//e := f.Apply()
//assert.Equal(t, nil, e)
}
func TestCommandExtractor(t *testing.T) {
packages := map[PackageType][]struct{ Name string; Version string; Input string } {
PackageTypeApk: []struct{ Name string; Version string; Input string }{
/*
{ Name: "alpine-baselayout", Version: "3.6.5-r0", Input: `alpine-baselayout-3.6.5-r0 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]` },
{ Name: "alpine-baselayout-data", Version: "3.6.5-r0", Input: `alpine-baselayout-data-3.6.5-r0 x86_64 {alpine-baselayout} (GPL-2.0-only) [installed]` },
{ Name: "alpine-keys", Version: "2.4-r1", Input: `alpine-keys-2.4-r1 x86_64 {alpine-keys} (MIT) [installed]` },
{ Name: "apk-tools", Version: "2.14.4-r0", Input: `apk-tools-2.14.4-r0 x86_64 {apk-tools} (GPL-2.0-only) [installed]` },
{ Name: "busybox", Version: "1.36.1-r29", Input: `busybox-1.36.1-r29 x86_64 {busybox} (GPL-2.0-only) [installed]` },
{ Name: "busybox-binsh", Version: "1.36.1-r20", Input: `busybox-binsh-1.36.1-r29 x86_64 {busybox} (GPL-2.0-only) [installed]` },
{ Name: "ca-certificates", Version: "20240705-r0", Input: `ca-certificates-20240705-r0 x86_64 {ca-certificates} (MPL-2.0 AND MIT) [installed]` },
{ Name: "ca-certificates-bundle", Version: "20240705-r0", Input: `ca-certificates-bundle-20240705-r0 x86_64 {ca-certificates} (MPL-2.0 AND MIT) [installed]` },
{ Name: "libcrypto3", Version: "3.3.1-r3", Input: `libcrypto3-3.3.1-r3 x86_64 {openssl} (Apache-2.0) [installed]` },
{ Name: "libssl3", Version: "3.3.1-r3", Input: `libssl3-3.3.1-r3 x86_64 {openssl} (Apache-2.0) [installed]` },
{ Name: "musl", Version: "1.2.5-r0", Input: `musl-1.2.5-r0 x86_64 {musl} (MIT) [installed]` },
{ Name: "musl-utils", Version: "1.2.5-r0", Input: `musl-utils-1.2.5-r0 x86_64 {musl} (MIT AND BSD-2-Clause AND GPL-2.0-or-later) [installed]` },
{ Name: "scanelf", Version: "1.3.7-r2", Input: `scanelf-1.3.7-r2 x86_64 {pax-utils} (GPL-2.0-only) [installed]` },
{ Name: "ssl_client", Version: "1.36.1-r29", Input: `ssl_client-1.36.1-r29 x86_64 {busybox} (GPL-2.0-only) [installed]` },
{ Name: "zlib", Version: "1.3.1-r1", Input: `zlib-1.3.1-r1 x86_64 {zlib} (Zlib) [installed]` },
*/
{ Name: "alpine-baselayout", Version: "3.6.5", Input: `alpine-baselayout-3.6.5-r0` },
{ Name: "alpine-baselayout-data", Version: "3.6.5", Input: `alpine-baselayout-data-3.6.5-r0` },
{ Name: "alpine-keys", Version: "2.4", Input: `alpine-keys-2.4-r1` },
{ Name: "apk-tools", Version: "2.14.4", Input: `apk-tools-2.14.4-r0` },
{ Name: "busybox", Version: "1.36.1", Input: `busybox-1.36.1-r29` },
{ Name: "busybox-binsh", Version: "1.36.1", Input: `busybox-binsh-1.36.1-r29` },
{ Name: "ca-certificates", Version: "20240705", Input: `ca-certificates-20240705-r0` },
{ Name: "ca-certificates-bundle", Version: "20240705", Input: `ca-certificates-bundle-20240705-r0` },
{ Name: "libcrypto3", Version: "3.3.1", Input: `libcrypto3-3.3.1-r3` },
{ Name: "libssl3", Version: "3.3.1", Input: `libssl3-3.3.1-r3` },
{ Name: "musl", Version: "1.2.5", Input: `musl-1.2.5-r0` },
{ Name: "musl-utils", Version: "1.2.5", Input: `musl-utils-1.2.5-r0` },
{ Name: "scanelf", Version: "1.3.7", Input: `scanelf-1.3.7-r2` },
{ Name: "ssl_client", Version: "1.36.1", Input: `ssl_client-1.36.1-r29` },
{ Name: "zlib", Version: "1.3.1", Input: `zlib-1.3.1-r1` },
},
PackageTypeApt: []struct{ Name string; Version string; Input string }{
{ Name: "bluez-meshd", Version: "5.64-0ubuntu1pop1~1674313994~22.04~579884f~dev", Input: `
Package: bluez-meshd
Status: install ok installed
Priority: optional
Section: admin
Installed-Size: 937
Maintainer: Ubuntu Bluetooth team <ubuntu-bluetooth@lists.ubuntu.com>
Architecture: amd64
Source: bluez
Version: 5.64-0ubuntu1pop1~1674313994~22.04~579884f~dev
Depends: libc6 (>= 2.34), libdbus-1-3 (>= 1.9.14), libglib2.0-0 (>= 2.28.0), libjson-c5 (>= 0.15), libreadline8 (>= 6.0)
Conffiles:
/etc/dbus-1/system.d/bluetooth-mesh.conf 95c2a66615065ad1195d5b647555c393
Description: bluetooth mesh daemon
The Bluetooth Mesh network is a new Bluetooth feature that extends "Bluetooth
Low Energy (BLE)".
.
This package provides daemon (meshd) and tools that provide Bluetooth mesh
functionality.
.
BlueZ is the official Linux Bluetooth protocol stack. It is an Open Source
project distributed under GNU General Public License (GPL).
Homepage: http://www.bluez.org
Original-Maintainer: Debian Bluetooth Maintainers <pkg-bluetooth-maintainers@lists.alioth.debian.org>
` },
{ Name: "dconf-gsettings-backend", Version: "0.40.0-3", Input: `
Package: dconf-gsettings-backend
Status: install ok installed
Priority: optional
Section: libs
Installed-Size: 83
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Multi-Arch: same
Source: dconf
Version: 0.40.0-3
Provides: gsettings-backend
Depends: dconf-service (<< 0.40.0-3.1~), dconf-service (>= 0.40.0-3), libdconf1 (= 0.40.0-3), libc6 (>= 2.14), libglib2.0-0 (>= 2.55.2)
Description: simple configuration storage system - GSettings back-end
DConf is a low-level key/value database designed for storing desktop
environment settings.
.
This package contains a back-end for GSettings. It is needed by
applications accessing settings through GSettings to set custom values
and listen for changes.
Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
Homepage: https://wiki.gnome.org/Projects/dconf
` },
{ Name: "cheese-common", Version: "41.1-1build1", Input: `
Package: cheese-common
Status: install ok installed
Priority: optional
Section: gnome
Installed-Size: 912
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: all
Multi-Arch: foreign
Source: cheese
Version: 41.1-1build1
Depends: dconf-gsettings-backend | gsettings-backend
Description: Common files for the Cheese tool to take pictures and videos
A webcam application that supports image and video capture. Makes
it easy to take photos and videos of you, your friends, pets or whatever
you want. Allows you to apply fancy visual effects, fine-control image
settings and has features such as Multi-Burst mode, Countdown timer
for photos.
.
This package contains the common files and translations.
Original-Maintainer: Debian GNOME Maintainers <pkg-gnome-maintainers@lists.alioth.debian.org>
Homepage: https://wiki.gnome.org/Apps/Cheese
` },
{ Name: "fonts-lohit-deva", Version: "2.95.4-4", Input: `
Package: fonts-lohit-deva
Status: install ok installed
Priority: optional
Section: fonts
Installed-Size: 193
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: all
Multi-Arch: foreign
Version: 2.95.4-4
Replaces: ttf-devanagari-fonts (<= 1:0.5.12)
Breaks: ttf-devanagari-fonts (<= 1:0.5.12)
Conffiles:
/etc/fonts/conf.avail/59-lohit-devanagari.conf 26750c27821421cef15176c5d6eb490e
/etc/fonts/conf.avail/66-lohit-devanagari.conf dfac9388b18ece1d53fed86785070f55
Description: Lohit TrueType font for Devanagari script
This package provides Lohit TrueType font for Devanagari script which
is used for writing Hindi, Kashmiri, Konkani, Marathi, Maithili, Nepali,
Sanskrit, and Sindhi languages.
Original-Maintainer: Debian Fonts Task Force <debian-fonts@lists.debian.org>
Homepage: https://pagure.io/lohit
` },
{ Name: "zstd", Version: "1.4.8+dfsg-3build1", Input: `
Package: zstd
Status: install ok installed
Priority: optional
Section: utils
Installed-Size: 1655
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Architecture: amd64
Source: libzstd
Version: 1.4.8+dfsg-3build1
Depends: libc6 (>= 2.34), libgcc-s1 (>= 3.3.1), liblz4-1 (>= 0.0~r127), liblzma5 (>= 5.1.1alpha+20120614), libstdc++6 (>= 12), zlib1g (>= 1:1.1.4)
Description: fast lossless compression algorithm -- CLI tool
Zstd, short for Zstandard, is a fast lossless compression algorithm, targeting
real-time compression scenarios at zlib-level compression ratio.
.
This package contains the CLI program implementing zstd.
Homepage: https://github.com/facebook/zstd
Original-Maintainer: Debian Med Packaging Team <debian-med-packaging@lists.alioth.debian.org>
` },
},
PackageTypeDnf: []struct{ Name string; Version string; Input string }{
{ Name: "man-pages-zh-CN", Version: "1.6.3.6-9.fc40", Input: `
man-pages-zh-CN.noarch 1.6.3.6-9.fc40 @fedora` },
{ Name: "memstrack", Version: "0.2.5-4.fc40", Input: `
memstrack.x86_64 0.2.5-4.fc40 @fedora` },
{ Name: "mercurial", Version: "6.7.4-3.fc40", Input: `
mercurial.x86_64 6.7.4-3.fc40 @updates` },
{ Name: "mesa-dri-drivers", Version: "24.1.7-1.fc40", Input: `
mesa-dri-drivers.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-filesystem", Version: "24.1.7-1.fc40", Input: `
mesa-filesystem.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-libEGL", Version: "24.1.7-1.fc40", Input: `
mesa-libEGL.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-libGL", Version: "24.1.7-1.fc40", Input: `
mesa-libGL.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-libgbm", Version: "24.1.7-1.fc40", Input: `
mesa-libgbm.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-libglapi", Version: "24.1.7-1.fc40", Input: `
mesa-libglapi.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mesa-va-drivers", Version: "24.1.7-1.fc40", Input: `
mesa-va-drivers.x86_64 24.1.7-1.fc40 @updates` },
{ Name: "mkfontscale", Version: "1.2.2-6.fc40", Input: `
mkfontscale.x86_64 1.2.2-6.fc40 @fedora` },
{ Name: "moby-engine", Version: "24.0.5-4.fc40", Input: `
moby-engine.x86_64 24.0.5-4.fc40 @fedora` },
{ Name: "mpdecimal", Version: "2.5.1-9.fc40", Input: `
mpdecimal.x86_64 2.5.1-9.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "mpfr", Version: "4.2.1-3.fc40", Input: `
mpfr.x86_64 4.2.1-3.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "mpg123-libs", Version: "1.31.3-4.fc40", Input: `
mpg123-libs.x86_64 1.31.3-4.fc40 @fedora` },
{ Name: "ncurses", Version: "6.4-12.20240127.fc40", Input: `
ncurses.x86_64 6.4-12.20240127.fc40 @fedora` },
{ Name: "ncurses-base", Version: "6.4-12.20240127.fc40", Input: `
ncurses-base.noarch 6.4-12.20240127.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "ncurses-libs", Version: "6.4-12.20240127.fc40", Input: `
ncurses-libs.x86_64 6.4-12.20240127.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "net-tools", Version: "2.0-0.69.20160912git.fc40", Input: `
net-tools.x86_64 2.0-0.69.20160912git.fc40 @fedora` },
{ Name: "nettle", Version: "3.9.1-6.fc40", Input: `
nettle.x86_64 3.9.1-6.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "nftables", Version: "1.0.9-3.fc40", Input: `
nftables.x86_64 1:1.0.9-3.fc40 @fedora` },
{ Name: "npth", Version: "1.7-1.fc40", Input: `
npth.x86_64 1.7-1.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "nspr", Version: "4.35.0-28.fc40", Input: `
nspr.x86_64 4.35.0-28.fc40 @updates` },
{ Name: "nss", Version: "3.103.0-1.fc40", Input: `
nss.x86_64 3.103.0-1.fc40 @updates` },
{ Name: "nss-softokn", Version: "3.103.0-1.fc40", Input: `
nss-softokn.x86_64 3.103.0-1.fc40 @updates` },
{ Name: "nss-softokn-freebl", Version: "3.103.0-1.fc40", Input: `
nss-softokn-freebl.x86_64 3.103.0-1.fc40 @updates` },
{ Name: "nss-sysinit", Version: "3.103.0-1.fc40", Input: `
nss-sysinit.x86_64 3.103.0-1.fc40 @updates` },
{ Name: "nss-util", Version: "3.103.0-1.fc40", Input: `
nss-util.x86_64 3.103.0-1.fc40 @updates` },
{ Name: "openjpeg2", Version: "2.5.2-1.fc40", Input: `
openjpeg2.x86_64 2.5.2-1.fc40 @fedora` },
{ Name: "openldap", Version: "2.6.7-1.fc40", Input: `
openldap.x86_64 2.6.7-1.fc40 @2c98ee0d5281429683938d93eb2a9aa4` },
{ Name: "openssh", Version: "9.6p1-1.fc40.4", Input: `
openssh.x86_64 9.6p1-1.fc40.4 @updates` },
{ Name: "openssh-clients", Version: "9.6p1-1.fc40.4", Input: `
openssh-clients.x86_64 9.6p1-1.fc40.4 @updates` },
{ Name: "openssl", Version: "3.2.2-3.fc40", Input: `
openssl.x86_64 1:3.2.2-3.fc40 @updates` },
{ Name: "openssl-libs", Version: "3.2.2-3.fc40", Input: `
openssl-libs.x86_64 1:3.2.2-3.fc40 @updates` },
{ Name: "opus", Version: "1.5.1-1.fc40", Input: `
opus.x86_64 1.5.1-1.fc40 @fedora` },
{ Name: "orc", Version: "0.4.39-1.fc40", Input: `
orc.x86_64 0.4.39-1.fc40 @updates` },
},
}
for _, pt := range SupportedPackageTypes {
cmd := pt.NewReadCommand()
for _, v := range packages[pt] {
pkg := NewPackage()
pkg.Name = v.Name
assert.Nil(t, cmd.Extractor([]byte(v.Input), pkg))
slog.Info("TestCommandExtractor()", "packagetype", pt, "name", pkg.Name, "package", pkg)
assert.Equal(t, v.Name, pkg.Name)
assert.Equal(t, v.Version, pkg.Version)
assert.Equal(t, "present", pkg.State)
}
}
}
func TestReadPackage(t *testing.T) {
decl := `
name: vim
version: latest
type: apk
`
p := NewPackage()
assert.NotNil(t, p)
m := &MockCommand{
CommandExists: func() error { return nil },
Executor: func(value any) ([]byte, error) {
return nil, nil
},
Extractor: func(output []byte, target any) error {
p.Name = "vim"
p.Version = "1.1.1"
p.State = "present"
return nil
},
}
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
assert.Equal(t, "latest", p.Version)
p.ReadCommand = (*command.Command)(m)
yaml, readErr := p.Read(context.Background())
assert.Nil(t, readErr)
assert.Greater(t, len(yaml), 0)
slog.Info("read()", "yaml", yaml)
assert.Equal(t, "1.1.1", p.Version)
slog.Info("resource: ", "package", p)
assert.Nil(t, p.Validate())
}
func TestReadAptPackage(t *testing.T) {
if ! PackageTypeApt.Exists() {
t.Skip("Unsupported package type")
}
decl := `
name: vim
required: ">1.1.1"
type: apt
`
p := NewPackage()
assert.NotNil(t, p)
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
assert.Equal(t, ">1.1.1", p.Required)
p.ReadCommand = NewAptReadCommand()
p.ReadCommand.Executor = func(value any) ([]byte, error) {
return []byte(`
Package: vim
Version: 1.2.2
`), nil
}
yaml, readErr := p.Read(context.Background())
assert.Nil(t, readErr)
assert.Greater(t, len(yaml), 0)
slog.Info("read()", "yaml", yaml)
assert.Equal(t, "1.2.2", p.Version)
assert.Nil(t, p.Validate())
}
func TestReadPackageError(t *testing.T) {
ctx := context.Background()
expected := fmt.Sprintf(`
name: missing
state: absent
type: %s
`, SystemPackageType)
decl := fmt.Sprintf(`
name: missing
type: %s
`, SystemPackageType)
p := NewPackage()
assert.NotNil(t, p)
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
assert.Nil(t, p.Init(nil))
p.ReadCommand = SystemPackageType.NewReadCommand()
/*
p.ReadCommand.Executor = func(value any) ([]byte, error) {
return []byte(``), fmt.Errorf("exit status 1 dpkg-query: package 'makef' is not installed and no information is available\nUse dpkg --info (= dpkg-deb --info) to examine archive files.\n")
}
*/
p.ResolveId(ctx)
yaml, readErr := p.Read(ctx)
assert.ErrorIs(t, readErr, ErrResourceStateAbsent)
slog.Info("TestReadPackageError", "package", p, "common", p.Common, "yaml", yaml)
assert.YAMLEq(t, expected, string(yaml))
slog.Info("read()", "yaml", yaml)
assert.Equal(t, "", p.Version)
assert.Nil(t, p.Validate())
}
func TestCreatePackage(t *testing.T) {
}
func TestPackageSetURI(t *testing.T) {
p := NewPackage()
assert.NotNil(t, p)
uri := folio.URI("package://" + "12345_key?type=apk").Parse()
e := p.Init(uri)
assert.Nil(t, e)
assert.Equal(t, "package", p.Type())
assert.Equal(t, "12345_key", p.Name)
}
func TestReadDebPackage(t *testing.T) {
if ! PackageTypeDeb.Exists() {
t.Skip("Unsupported package type")
}
decl := `
name: vim
source: vim-8.2.3995-1ubuntu2.17.deb
type: deb
`
p := NewPackage()
assert.NotNil(t, p)
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
p.ReadCommand = NewDebReadCommand()
p.ReadCommand.Executor = func(value any) ([]byte, error) {
return []byte(`
Package: vim
Version: 1.2.2
`), nil
}
yaml, readErr := p.Read(context.Background())
assert.Nil(t, readErr)
slog.Info("Package.Read()", "package", p)
assert.Greater(t, len(yaml), 0)
slog.Info("read()", "yaml", yaml)
assert.Equal(t, "1.2.2", p.Version)
assert.Nil(t, p.Validate())
}
func TestPackageTypeErr(t *testing.T) {
decl := `
name: vim
source: vim-8.2.3995-1ubuntu2.17.deb
type: deb
`
p := NewPackage()
assert.NotNil(t, p)
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
p.ReadCommand = NewDebReadCommand()
p.ReadCommand.CommandExists = func() error { return command.ErrUnknownCommand }
p.ReadCommand.Executor = func(value any) ([]byte, error) {
return []byte(`
Package: vim
Version: 1.2.2
`), nil
}
_, readErr := p.Read(context.Background())
assert.ErrorIs(t, readErr, ErrUnsupportedPackageType)
}
func TestPackageSourceRef(t *testing.T) {
decl := `
name: vim
sourceref: https://localhost/vim-8.2.3995-1ubuntu2.17.deb
type: deb
`
p := NewPackage()
assert.NotNil(t, p)
loadErr := p.LoadDecl(decl)
assert.Nil(t, loadErr)
p.ReadCommand = NewDebReadCommand()
p.ReadCommand.CommandExists = func() error { return command.ErrUnknownCommand }
p.ReadCommand.Executor = func(value any) ([]byte, error) {
return []byte(`
Package: vim
Version: 1.2.2
`), nil
}
_, readErr := p.Read(context.Background())
assert.ErrorIs(t, readErr, ErrUnsupportedPackageType)
}