issue 1840/S9: prove pacman's output puts no command line or environment on the bus
A fixture of pacman and checkupdates output holding command lines, environment variables and messages leaves only names, versions and repositories in installed, updates and package.changed, and no command the keeper runs names a package, a foreign one least of all.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
package main
|
||||
|
||||
// What the keeper puts on the bus is only its named fields (novox/hq ADR 0507 §1; acceptance 1840/AC7): pacman's
|
||||
// output holding command lines, environment variables and messages leaves none of them in a value or an event,
|
||||
// and no command the keeper runs names a package, a foreign one least of all. (busshapes_test.go holds every
|
||||
// shape to its named fields.)
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestPacmanOutputHoldingCommandLinesAndEnvironmentPutsNeitherOnTheBus(t *testing.T) {
|
||||
dir := filepath.Join("testdata", "pacman-output-with-command-lines-and-environment")
|
||||
read := func(name string) string {
|
||||
b, err := os.ReadFile(filepath.Join(dir, name))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return string(b)
|
||||
}
|
||||
db := &pacmanDB{sl: read("pacman-Sl"), checkup: Ran{Stdout: read("checkupdates")}}
|
||||
db.set(read("pacman-Q"), read("pacman-Qeq"))
|
||||
k, states, ev, clock, w := newTestKeeper(db)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
done := make(chan error, 1)
|
||||
go func() { done <- k.Run(ctx) }()
|
||||
for deadline := time.Now().Add(5 * time.Second); time.Now().Before(deadline); time.Sleep(time.Millisecond) {
|
||||
if e, _ := states.store(StateUpdates).Get("node-a"); e != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
clock.Advance(time.Minute)
|
||||
w.c <- LockReleased
|
||||
w.c <- MirrorsRewritten
|
||||
time.Sleep(20 * time.Millisecond)
|
||||
cancel()
|
||||
<-done
|
||||
|
||||
var onBus []string
|
||||
for _, name := range []string{StateInstalled, StateUpdates} {
|
||||
s := states.store(name)
|
||||
keys, _ := s.Keys()
|
||||
for _, key := range keys {
|
||||
e, _ := s.Get(key)
|
||||
onBus = append(onBus, name+"."+key+" "+string(e.Value))
|
||||
}
|
||||
}
|
||||
events := ev.Take()
|
||||
if len(events) == 0 {
|
||||
t.Fatal("the first write said nothing")
|
||||
}
|
||||
for _, e := range events {
|
||||
body, _ := json.Marshal(e.body)
|
||||
onBus = append(onBus, e.name+" "+string(body))
|
||||
}
|
||||
if len(onBus) < 3 {
|
||||
t.Fatalf("on the bus: %v", onBus)
|
||||
}
|
||||
whole := strings.Join(onBus, "\n")
|
||||
for _, never := range []string{"=", "sudo", "--noconfirm", "/", "rm", "warning", "hunter2", "Synchronizing", "HOME", "TOKEN", "SECRET"} {
|
||||
if strings.Contains(whole, never) {
|
||||
t.Errorf("%q reached the bus:\n%s", never, whole)
|
||||
}
|
||||
}
|
||||
var inst InstalledValue
|
||||
e, _ := states.store(StateInstalled).Get("node-a")
|
||||
json.Unmarshal(e.Value, &inst)
|
||||
if !samePackages(inst.Packages, []InstalledPackage{{"glibc", "2.42-1", false, "core"}, {"yay", "12.0-1", true, RepoForeign}, {"zsh", "5.9-1", true, "extra"}}) {
|
||||
t.Errorf("the packages are read, the rest left out: %+v", inst.Packages)
|
||||
}
|
||||
var up UpdatesValue
|
||||
e, _ = states.store(StateUpdates).Get("node-a")
|
||||
json.Unmarshal(e.Value, &up)
|
||||
if len(up.Packages) != 1 || up.Packages[0] != (VersionChange{"glibc", "2.42-1", "2.42-2"}) {
|
||||
t.Errorf("updates: %+v", up)
|
||||
}
|
||||
|
||||
// no command the keeper ran names a package; the foreign one least of all.
|
||||
db.mu.Lock()
|
||||
defer db.mu.Unlock()
|
||||
for _, c := range db.commands {
|
||||
switch c {
|
||||
case "pacman -Q", "pacman -Qeq", "pacman -Sl", "checkupdates":
|
||||
default:
|
||||
t.Errorf("the keeper ran %q", c)
|
||||
}
|
||||
if strings.Contains(c, "yay") {
|
||||
t.Errorf("a command named the foreign package: %q", c)
|
||||
}
|
||||
}
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
glibc 2.42-1 -> 2.42-2
|
||||
zsh 5.9-1 -> 5.9-2 PASSWORD=hunter2
|
||||
env FOO=bar -> /bin/sh
|
||||
:: Synchronizing package databases...
|
||||
Vendored
+9
@@ -0,0 +1,9 @@
|
||||
glibc 2.42-1
|
||||
sudo pacman -Syu --noconfirm
|
||||
yay 12.0-1
|
||||
LD_PRELOAD=/tmp/hook.so 1.0-1
|
||||
zsh 5.9-1
|
||||
bash 5.2-1 HOME=/root
|
||||
evil 1.0;rm-rf
|
||||
PATH=/usr/bin:/bin
|
||||
warning: could not get file information for etc/secret
|
||||
modules/pacman/cmd/pacman-tools/testdata/pacman-output-with-command-lines-and-environment/pacman-Qeq
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
yay
|
||||
zsh
|
||||
TOKEN=abc
|
||||
Vendored
+3
@@ -0,0 +1,3 @@
|
||||
core glibc 2.42-1 [installed]
|
||||
extra zsh 5.9-1 [installed]
|
||||
extra SECRET=x 1-1
|
||||
Reference in New Issue
Block a user