Skip to content

Commit

Permalink
container: add nested RHSM rpm test
Browse files Browse the repository at this point in the history
This commit adds a test that ensures that access to subscribed
content works in a nested container similar to how we run the
nested container in bootc-image-builder. I.e. here we run in
a privilidged container that then runs a normal container to
depsolve against that.

The test works by running the already existing
`TestDNFJsonWorkWithSubscribedContent` inside the container to
double check that subscribed content is available both from the
host and when nesting.

The extra complication is that for efficiency we compile the
test binary on the host (to avoid having to have a go toolchain
inside the container) which means the container needs to have a
recent version of glibc (building our code with CGO_ENABLED=0
does not work) to support developing/running tests on f41.
  • Loading branch information
mvo5 committed Nov 6, 2024
1 parent 9a71708 commit 37da578
Showing 1 changed file with 70 additions and 15 deletions.
85 changes: 70 additions & 15 deletions bib/internal/container/solver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os/exec"
"path/filepath"
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/assert"
Expand All @@ -18,17 +19,29 @@ import (
)

const (
dnfTestingImageRHEL = "registry.access.redhat.com/ubi9:latest"
dnfTestingImageCentos = "quay.io/centos/centos:stream9"
dnfTestingImageRHEL = "registry.access.redhat.com/ubi9:latest"
dnfTestingImageCentos = "quay.io/centos/centos:stream9"
dnfTestingImageFedoraLatest = "registry.fedoraproject.org/fedora:latest"
)

func TestDNFJsonWorks(t *testing.T) {
func ensureCanRunDNFJsonTests(t *testing.T) {
if os.Geteuid() != 0 {
t.Skip("skipping test; not running as root")
}
if _, err := os.Stat("/usr/libexec/osbuild-depsolve-dnf"); err != nil {
t.Skip("cannot find /usr/libexec/osbuild-depsolve-dnf")
}
}

func ensureAMD64(t *testing.T) {
if runtime.GOARCH != "amd64" {
t.Skip("skipping test; only runs on x86_64")
}
}

func TestDNFJsonWorks(t *testing.T) {
ensureCanRunDNFJsonTests(t)

cacheRoot := t.TempDir()

cnt, err := container.New(dnfTestingImageCentos)
Expand Down Expand Up @@ -84,9 +97,7 @@ func TestDNFInitGivesAccessToSubscribedContent(t *testing.T) {
if os.Geteuid() != 0 {
t.Skip("skipping test; not running as root")
}
if runtime.GOARCH != "amd64" {
t.Skip("skipping test; only runs on x86_64")
}
ensureAMD64(t)

restore := subscribeMachine(t)
defer restore()
Expand All @@ -102,15 +113,8 @@ func TestDNFInitGivesAccessToSubscribedContent(t *testing.T) {
}

func TestDNFJsonWorkWithSubscribedContent(t *testing.T) {
if os.Geteuid() != 0 {
t.Skip("skipping test; not running as root")
}
if runtime.GOARCH != "amd64" {
t.Skip("skipping test; only runs on x86_64")
}
if _, err := os.Stat("/usr/libexec/osbuild-depsolve-dnf"); err != nil {
t.Skip("cannot find /usr/libexec/osbuild-depsolve-dnf")
}
ensureCanRunDNFJsonTests(t)
ensureAMD64(t)
cacheRoot := t.TempDir()

restore := subscribeMachine(t)
Expand All @@ -136,3 +140,54 @@ func TestDNFJsonWorkWithSubscribedContent(t *testing.T) {
require.NoError(t, err)
assert.True(t, len(res.Packages) > 0)
}

func runCmd(t *testing.T, args ...string) {
cmd := exec.Command(args[0], args[1:]...)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
require.NoError(t, err)
}

func TestDNFJsonWorkWithSubscribedContentNestedContainers(t *testing.T) {
ensureCanRunDNFJsonTests(t)
ensureAMD64(t)
tmpdir := t.TempDir()

restore := subscribeMachine(t)
defer restore()

// build a test binary from the existing
// TestDNFJsonWorkWithSubscribedContent that is then
// transfered and run *inside* the centos container
testBinary := filepath.Join(tmpdir, "dnftest")
runCmd(t, "go", "test",
"-c",
"-o", testBinary,
"-run", "^TestDNFJsonWorkWithSubscribedContent$")

output, err := exec.Command(
"podman", "run", "--rm",
"--privileged",
"--init",
"--detach",
"--entrypoint", "sleep",
// use a fedora container as intermediate so that we
// always have the latest glibc (we cannot fully
// static link the test)
dnfTestingImageFedoraLatest,
"infinity",
).Output()
require.NoError(t, err, string(output))
cntID := strings.TrimSpace(string(output))
defer func() {
exec.Command("podman", "stop", cntID).Run()

Check failure on line 184 in bib/internal/container/solver_test.go

View workflow job for this annotation

GitHub Actions / ⌨ Lint & unittests

Error return value of `(*os/exec.Cmd).Run` is not checked (errcheck)
}()

runCmd(t, "podman", "cp", testBinary, cntID+":/dnftest")
// we need these test dependencies inside the container
runCmd(t, "podman", "exec", cntID, "dnf", "install", "-y",
"gpgme", "podman")
// run the test
runCmd(t, "podman", "exec", cntID, "/dnftest")
}

0 comments on commit 37da578

Please sign in to comment.