All checks were successful
Test / Create distribution (push) Successful in 1m0s
Test / Sandbox (push) Successful in 2m45s
Test / Hakurei (push) Successful in 3m47s
Test / ShareFS (push) Successful in 3m44s
Test / Sandbox (race detector) (push) Successful in 5m14s
Test / Hakurei (race detector) (push) Successful in 6m21s
Test / Flake checks (push) Successful in 1m19s
This is cleaner with less shared state. Signed-off-by: Ophestra <cat@gensokyo.uk>
171 lines
4.2 KiB
Go
171 lines
4.2 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"syscall"
|
|
"testing"
|
|
"unsafe"
|
|
|
|
"hakurei.app/internal/pkg"
|
|
"hakurei.app/internal/rosa"
|
|
"hakurei.app/message"
|
|
)
|
|
|
|
func TestInfo(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
testCases := []struct {
|
|
name string
|
|
args []string
|
|
status map[string]string
|
|
report string
|
|
want string
|
|
wantErr any
|
|
}{
|
|
{"qemu", []string{"qemu"}, nil, "", `
|
|
name : qemu-` + rosa.Std.Version(rosa.QEMU) + `
|
|
description : a generic and open source machine emulator and virtualizer
|
|
website : https://www.qemu.org
|
|
depends on : glib-` + rosa.Std.Version(rosa.GLib) + ` zstd-` + rosa.Std.Version(rosa.Zstd) + `
|
|
`, nil},
|
|
|
|
{"multi", []string{"hakurei", "hakurei-dist"}, nil, "", `
|
|
name : hakurei-` + rosa.Std.Version(rosa.Hakurei) + `
|
|
description : low-level userspace tooling for Rosa OS
|
|
website : https://hakurei.app
|
|
|
|
name : hakurei-dist-` + rosa.Std.Version(rosa.HakureiDist) + `
|
|
description : low-level userspace tooling for Rosa OS (distribution tarball)
|
|
website : https://hakurei.app
|
|
`, nil},
|
|
|
|
{"nonexistent", []string{"zlib", "\x00"}, nil, "", `
|
|
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
|
description : lossless data-compression library
|
|
website : https://zlib.net
|
|
|
|
`, fmt.Errorf("unknown artifact %q", "\x00")},
|
|
|
|
{"status cache", []string{"zlib", "zstd"}, map[string]string{
|
|
"zstd": "internal/pkg (amd64) on satori\n",
|
|
"hakurei": "internal/pkg (amd64) on satori\n\n",
|
|
}, "", `
|
|
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
|
description : lossless data-compression library
|
|
website : https://zlib.net
|
|
status : not yet cured
|
|
|
|
name : zstd-` + rosa.Std.Version(rosa.Zstd) + `
|
|
description : a fast compression algorithm
|
|
website : https://facebook.github.io/zstd
|
|
status : internal/pkg (amd64) on satori
|
|
`, nil},
|
|
|
|
{"status cache perm", []string{"zlib"}, map[string]string{
|
|
"zlib": "\x00",
|
|
}, "", `
|
|
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
|
description : lossless data-compression library
|
|
website : https://zlib.net
|
|
`, func(cm *cache) error {
|
|
return &os.PathError{
|
|
Op: "open",
|
|
Path: filepath.Join(cm.base, "status", pkg.Encode(cm.c.Ident(rosa.Std.Load(rosa.Zlib)).Value())),
|
|
Err: syscall.EACCES,
|
|
}
|
|
}},
|
|
|
|
{"status report", []string{"zlib"}, nil, strings.Repeat("\x00", len(pkg.Checksum{})+8), `
|
|
name : zlib-` + rosa.Std.Version(rosa.Zlib) + `
|
|
description : lossless data-compression library
|
|
website : https://zlib.net
|
|
status : not in report
|
|
`, nil},
|
|
}
|
|
for _, tc := range testCases {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
var (
|
|
cm *cache
|
|
buf strings.Builder
|
|
rp string
|
|
)
|
|
|
|
if tc.status != nil || tc.report != "" {
|
|
cm = &cache{
|
|
ctx: context.Background(),
|
|
msg: message.New(log.New(os.Stderr, "info: ", 0)),
|
|
base: t.TempDir(),
|
|
}
|
|
defer cm.Close()
|
|
}
|
|
|
|
if tc.report != "" {
|
|
rp = filepath.Join(t.TempDir(), "report")
|
|
if err := os.WriteFile(
|
|
rp,
|
|
unsafe.Slice(unsafe.StringData(tc.report), len(tc.report)),
|
|
0400,
|
|
); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
if tc.status != nil {
|
|
for name, status := range tc.status {
|
|
p, ok := rosa.ResolveName(name)
|
|
if !ok {
|
|
t.Fatalf("invalid name %q", name)
|
|
}
|
|
perm := os.FileMode(0400)
|
|
if status == "\x00" {
|
|
perm = 0
|
|
}
|
|
if err := cm.Do(func(cache *pkg.Cache) error {
|
|
return os.WriteFile(filepath.Join(
|
|
cm.base,
|
|
"status",
|
|
pkg.Encode(cache.Ident(rosa.Std.Load(p)).Value()),
|
|
), unsafe.Slice(unsafe.StringData(status), len(status)), perm)
|
|
}); err != nil {
|
|
t.Fatalf("Do: error = %v", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
var wantErr error
|
|
switch c := tc.wantErr.(type) {
|
|
case error:
|
|
wantErr = c
|
|
case func(cm *cache) error:
|
|
wantErr = c(cm)
|
|
default:
|
|
if tc.wantErr != nil {
|
|
t.Fatalf("invalid wantErr %#v", tc.wantErr)
|
|
}
|
|
}
|
|
|
|
if err := commandInfo(
|
|
cm,
|
|
tc.args,
|
|
&buf,
|
|
cm != nil,
|
|
rp,
|
|
); !reflect.DeepEqual(err, wantErr) {
|
|
t.Fatalf("commandInfo: error = %v, want %v", err, wantErr)
|
|
}
|
|
|
|
if got := buf.String(); got != strings.TrimPrefix(tc.want, "\n") {
|
|
t.Errorf("commandInfo:\n%s\nwant\n%s", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|