add test for the wall app

Signed-off-by: GnomeZworc <nicolas.boufidjeline@g3e.fr>
This commit is contained in:
GnomeZworc 2026-04-25 19:37:17 +02:00
commit 9e287e4e6a
Signed by: nicolas.boufideline
GPG key ID: 4406BBBF8845D632
15 changed files with 3022 additions and 1 deletions

View file

@ -0,0 +1,284 @@
package rpm
import (
"bytes"
"compress/gzip"
"encoding/xml"
"fmt"
"os"
"path/filepath"
"testing"
)
// buildPrimaryGz creates a gzipped primary.xml with the given packages.
// Each entry is {name, locationHref}.
func buildPrimaryGz(t *testing.T, pkgs []struct{ name, href string }) []byte {
t.Helper()
var buf bytes.Buffer
buf.WriteString(`<?xml version="1.0" encoding="UTF-8"?>`)
fmt.Fprintf(&buf, `<metadata xmlns="http://linux.duke.edu/metadata/common" packages="%d">`, len(pkgs))
for _, p := range pkgs {
fmt.Fprintf(&buf,
`<package type="rpm"><name>%s</name><location href="%s"/></package>`,
p.name, p.href)
}
buf.WriteString(`</metadata>`)
var gz bytes.Buffer
gzw := gzip.NewWriter(&gz)
gzw.Write(buf.Bytes())
gzw.Close()
return gz.Bytes()
}
// buildRepoMD creates a minimal repomd.xml pointing to the given primary href.
func buildRepoMD(t *testing.T, primaryHref string) []byte {
t.Helper()
repomd := RepoMD{
Data: []RepoMDEntry{{
Type: "primary",
Location: RepoMDLocation{Href: primaryHref},
Checksum: RepoMDChecksum{Type: "sha256", Value: "placeholder"},
OpenChecksum: RepoMDChecksum{Type: "sha256", Value: "placeholder"},
}},
}
out, err := xml.MarshalIndent(repomd, "", " ")
if err != nil {
t.Fatalf("marshal repomd: %v", err)
}
return append([]byte(xml.Header), out...)
}
// setupRepo creates a local repo dir with a primary.xml.gz, a .primary-source
// marker and a repomd.xml. It creates the given rpm files on disk.
func setupRepo(t *testing.T, pkgs []struct{ name, href string }, presentOnDisk []string) string {
t.Helper()
dir := t.TempDir()
repodata := filepath.Join(dir, "repodata")
os.MkdirAll(repodata, 0o755)
// Upstream primary at a hashed path (mimics real layout).
upstreamPrimary := "repodata/upstream-primary.xml.gz"
if err := os.WriteFile(filepath.Join(dir, upstreamPrimary), buildPrimaryGz(t, pkgs), 0o644); err != nil {
t.Fatalf("write upstream primary: %v", err)
}
// .primary-source marker.
if err := os.WriteFile(filepath.Join(repodata, PrimarySourceFile), []byte(upstreamPrimary), 0o644); err != nil {
t.Fatalf("write .primary-source: %v", err)
}
// repomd.xml pointing at local primary (which doesn't exist yet — regen will create it).
if err := os.WriteFile(filepath.Join(repodata, "repomd.xml"), buildRepoMD(t, localPrimaryHref), 0o644); err != nil {
t.Fatalf("write repomd.xml: %v", err)
}
// Create selected rpm files on disk.
for _, href := range presentOnDisk {
dest := filepath.Join(dir, filepath.FromSlash(href))
os.MkdirAll(filepath.Dir(dest), 0o755)
if err := os.WriteFile(dest, []byte("fake-rpm"), 0o644); err != nil {
t.Fatalf("write rpm %s: %v", href, err)
}
}
return dir
}
// parsePrimaryGz decompresses and parses a primary.xml.gz, returning package hrefs.
func parsePrimaryGz(t *testing.T, path string) []string {
t.Helper()
data, err := os.ReadFile(path)
if err != nil {
t.Fatalf("read primary.xml.gz: %v", err)
}
gz, err := gzip.NewReader(bytes.NewReader(data))
if err != nil {
t.Fatalf("open gzip: %v", err)
}
defer gz.Close()
var meta filterableMetadata
if err := xml.NewDecoder(gz).Decode(&meta); err != nil {
t.Fatalf("parse primary.xml: %v", err)
}
hrefs := make([]string, len(meta.Packages))
for i, p := range meta.Packages {
hrefs[i] = p.Location.Href
}
return hrefs
}
// --- InitEmptyRepo ---
func TestInitEmptyRepo_createsStructure(t *testing.T) {
dir := t.TempDir()
if err := InitEmptyRepo(dir); err != nil {
t.Fatalf("InitEmptyRepo: %v", err)
}
for _, path := range []string{
filepath.Join(dir, "repodata"),
filepath.Join(dir, "Packages"),
filepath.Join(dir, "repodata", "repomd.xml"),
filepath.Join(dir, localPrimaryHref),
} {
if _, err := os.Stat(path); err != nil {
t.Errorf("expected %s to exist: %v", path, err)
}
}
}
func TestInitEmptyRepo_repomdIsValid(t *testing.T) {
dir := t.TempDir()
InitEmptyRepo(dir)
data, _ := os.ReadFile(filepath.Join(dir, "repodata", "repomd.xml"))
var repomd RepoMD
if err := xml.Unmarshal(data, &repomd); err != nil {
t.Fatalf("repomd.xml is not valid XML: %v", err)
}
if len(repomd.Data) == 0 {
t.Error("expected at least one entry in repomd.xml")
}
if repomd.Data[0].Type != "primary" {
t.Errorf("first entry type: got %q, want primary", repomd.Data[0].Type)
}
}
func TestInitEmptyRepo_primaryIsEmpty(t *testing.T) {
dir := t.TempDir()
InitEmptyRepo(dir)
hrefs := parsePrimaryGz(t, filepath.Join(dir, localPrimaryHref))
if len(hrefs) != 0 {
t.Errorf("expected 0 packages in empty repo, got %d", len(hrefs))
}
}
func TestInitEmptyRepo_idempotent(t *testing.T) {
dir := t.TempDir()
InitEmptyRepo(dir)
repomdBefore, _ := os.ReadFile(filepath.Join(dir, "repodata", "repomd.xml"))
InitEmptyRepo(dir) // second call
repomdAfter, _ := os.ReadFile(filepath.Join(dir, "repodata", "repomd.xml"))
if !bytes.Equal(repomdBefore, repomdAfter) {
t.Error("second InitEmptyRepo modified repomd.xml")
}
}
// --- RegenerateMetadata ---
func TestRegenerateMetadata_keepsOnlyPresentFiles(t *testing.T) {
allPkgs := []struct{ name, href string }{
{"curl", "Packages/curl-7.88-1.x86_64.rpm"},
{"wget", "Packages/wget-1.21-1.x86_64.rpm"},
{"vim", "Packages/vim-9.0-1.x86_64.rpm"},
}
// Only curl and vim are on disk.
presentOnDisk := []string{"Packages/curl-7.88-1.x86_64.rpm", "Packages/vim-9.0-1.x86_64.rpm"}
dir := setupRepo(t, allPkgs, presentOnDisk)
if err := RegenerateMetadata(dir); err != nil {
t.Fatalf("RegenerateMetadata: %v", err)
}
hrefs := parsePrimaryGz(t, filepath.Join(dir, localPrimaryHref))
if len(hrefs) != 2 {
t.Fatalf("expected 2 packages, got %d: %v", len(hrefs), hrefs)
}
hrefSet := map[string]bool{hrefs[0]: true, hrefs[1]: true}
if !hrefSet["Packages/curl-7.88-1.x86_64.rpm"] {
t.Error("expected curl in output")
}
if !hrefSet["Packages/vim-9.0-1.x86_64.rpm"] {
t.Error("expected vim in output")
}
if hrefSet["Packages/wget-1.21-1.x86_64.rpm"] {
t.Error("wget should have been filtered out (not on disk)")
}
}
func TestRegenerateMetadata_allAbsent(t *testing.T) {
allPkgs := []struct{ name, href string }{
{"curl", "Packages/curl-7.88-1.x86_64.rpm"},
{"wget", "Packages/wget-1.21-1.x86_64.rpm"},
}
dir := setupRepo(t, allPkgs, nil) // nothing on disk
if err := RegenerateMetadata(dir); err != nil {
t.Fatalf("RegenerateMetadata: %v", err)
}
hrefs := parsePrimaryGz(t, filepath.Join(dir, localPrimaryHref))
if len(hrefs) != 0 {
t.Errorf("expected 0 packages, got %d", len(hrefs))
}
}
func TestRegenerateMetadata_updatesRepoMD(t *testing.T) {
allPkgs := []struct{ name, href string }{
{"curl", "Packages/curl-7.88-1.x86_64.rpm"},
}
dir := setupRepo(t, allPkgs, []string{"Packages/curl-7.88-1.x86_64.rpm"})
if err := RegenerateMetadata(dir); err != nil {
t.Fatalf("RegenerateMetadata: %v", err)
}
data, _ := os.ReadFile(filepath.Join(dir, "repodata", "repomd.xml"))
var repomd RepoMD
xml.Unmarshal(data, &repomd)
var primary *RepoMDEntry
for i := range repomd.Data {
if repomd.Data[i].Type == "primary" {
primary = &repomd.Data[i]
}
}
if primary == nil {
t.Fatal("no primary entry in repomd.xml after regen")
}
if primary.Location.Href != localPrimaryHref {
t.Errorf("Location.Href: got %q, want %q", primary.Location.Href, localPrimaryHref)
}
if primary.Checksum.Type != "sha256" {
t.Errorf("Checksum.Type: got %q, want sha256", primary.Checksum.Type)
}
if primary.Checksum.Value == "placeholder" {
t.Error("checksum was not updated from placeholder")
}
if primary.Size == 0 {
t.Error("Size should be non-zero after regen")
}
}
func TestRegenerateMetadata_alwaysFiltersFromUpstream(t *testing.T) {
// Simulates two successive approvals — regen must always read upstream, not the
// previously-filtered local primary.
allPkgs := []struct{ name, href string }{
{"curl", "Packages/curl-7.88-1.x86_64.rpm"},
{"wget", "Packages/wget-1.21-1.x86_64.rpm"},
{"vim", "Packages/vim-9.0-1.x86_64.rpm"},
}
dir := setupRepo(t, allPkgs, []string{"Packages/curl-7.88-1.x86_64.rpm"})
// First regen: only curl on disk.
RegenerateMetadata(dir)
hrefs := parsePrimaryGz(t, filepath.Join(dir, localPrimaryHref))
if len(hrefs) != 1 {
t.Fatalf("after first regen: expected 1, got %d", len(hrefs))
}
// Add wget to disk, regen again — vim still absent.
dest := filepath.Join(dir, "Packages", "wget-1.21-1.x86_64.rpm")
os.WriteFile(dest, []byte("fake"), 0o644)
RegenerateMetadata(dir)
hrefs = parsePrimaryGz(t, filepath.Join(dir, localPrimaryHref))
if len(hrefs) != 2 {
t.Fatalf("after second regen: expected 2, got %d: %v", len(hrefs), hrefs)
}
}