Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

package e2e tests in rpm #22395

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open

Conversation

edsantiago
Copy link
Collaborator

@edsantiago edsantiago commented Apr 16, 2024

Allow other parties to run e2e tests against an rpm-installed podman.

Much trickier than I'd predicted. Split into three commits. Please review those separately for your sanity.

Judgment call: I'm shoehorning these into the existing podman-tests rpm which until now has only had system tests. If there's any objection, or any strong argument for breaking out yet another new subpackage, please speak now.

e2e tests are now included in the podman-tests rpm

@openshift-ci openshift-ci bot added the do-not-merge/release-note-label-needed Enforce release-note requirement, even if just None label Apr 16, 2024
Copy link
Contributor

openshift-ci bot commented Apr 16, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: edsantiago

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added approved Indicates a PR has been approved by an approver from all required OWNERS files. release-note and removed do-not-merge/release-note-label-needed Enforce release-note requirement, even if just None labels Apr 16, 2024
Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

1 similar comment
Copy link

Ephemeral COPR build failed. @containers/packit-build please check.

Copy link
Collaborator Author

@edsantiago edsantiago left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HTH

Comment on lines -246 to -250
// Verify that id is correct
inspect := podmanTest.Podman([]string{"inspect", string(id)})
inspect.WaitWithDefaultTimeout()
data := inspect.InspectImageJSON()
Expect("sha256:" + data[0].ID).To(Equal(string(id)))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judgment call: I see no reason to test this

Comment on lines -464 to -463
podmanTest.StopRemoteService()
podmanTest.StartRemoteService()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judgment call: I have no idea why this was necessary, and I deem it pointless. Nuked.

podmanTest.StopRemoteService()
podmanTest.StartRemoteService()
} else {
Skip("Only valid at remote test")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Judgment call: I see no reason to test this only in remote.

Comment on lines -196 to -206
cwd, _ := os.Getwd()
INTEGRATION_ROOT = filepath.Join(cwd, "../../")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason not to nuke this now-empty function?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no good to remove, and thanks to ab29ff2 it only needs to happen in one place.

@@ -1424,10 +1416,6 @@ func CopyDirectory(srcDir, dest string) error {
}
}

if err := os.Lchown(destPath, int(stat.Uid), int(stat.Gid)); err != nil {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't work rootless. I suspect this was a copy-pasteism.

@@ -48,11 +48,10 @@ var _ = Describe("Podman login and logout", func() {

testImg = strings.Join([]string{server, "test-alpine"}, "/")

certDirPath = filepath.Join(os.Getenv("HOME"), ".config/containers/certs.d", server)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yuk. Let's try not to do this.

@@ -61,7 +60,7 @@ var _ = Describe("Podman login and logout", func() {
"-e", strings.Join([]string{"REGISTRY_HTTP_ADDR=0.0.0.0", strconv.Itoa(port)}, ":"), "--name", "registry", "-v",
strings.Join([]string{authPath, "/auth:Z"}, ":"), "-e", "REGISTRY_AUTH=htpasswd", "-e",
"REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm", "-e", "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd",
"-v", strings.Join([]string{certPath, "/certs:Z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
"-v", strings.Join([]string{certDirPath, "/certs:Z"}, ":"), "-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt",
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For ease of review: this was an oops. certPath is in cwd, which in rpm is /usr/share/podman/tests/e2e, which is not writable by rootless and cannot be relabeled. The intention here was obviously to volume mount the copy, it just sort of never happened that way and nobody ever noticed.

@@ -4093,7 +4093,7 @@ o: {{ .Options.o }}`})
It("persistentVolumeClaim with source", func() {
fileName := "data"
expectedFileContent := "Test"
tarFilePath := filepath.Join(os.TempDir(), "podmanVolumeSource.tgz")
tarFilePath := filepath.Join(podmanTest.TempDir, "podmanVolumeSource.tgz")
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yuk. This was creating a file in $TMPDIR and never cleaning it up. Not just littering: this prevented running rootless after running as root.

@@ -625,7 +625,7 @@ VOLUME /test/`, ALPINE)

session = podmanTest.Podman([]string{"run", "--rm", "-v", ".:/app:O", ALPINE, "ls", "/app"})
session.WaitWithDefaultTimeout()
Expect(session.OutputToString()).To(ContainSubstring(filepath.Base(CurrentSpecReport().FileName())))
Expect(session.OutputToString()).To(ContainSubstring(" quadlet "))
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rpm package includes a compiled ginkgo binary, but no source files. I could or(source or binary), but this seems good enough.

@edsantiago
Copy link
Collaborator Author

Blue-robot failures look real:

+ ./test/tools/build/ginkgo build test/e2e
Failed to compile e2e:

go build github.com/containers/storage/pkg/devicemapper:
# pkg-config --cflags  -- devmapper
Package devmapper was not found in the pkg-config search path.
Perhaps you should add the directory containing `devmapper.pc'
to the PKG_CONFIG_PATH environment variable
Package 'devmapper', required by 'virtual:world', not found
pkg-config: exit status 1
# github.com/mattn/go-sqlite3
../../vendor/github.com/mattn/go-sqlite3/sqlite3.go:85:1: warning: ‘_sqlite3_exec’ defined but not used [-Wunused-function]
   85 | _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* changes)
      | ^~~~~~~~~~~~~

ginkgo build failed

...but it's not something I'm going to look into today.

@edsantiago edsantiago marked this pull request as draft April 16, 2024 21:10
@openshift-ci openshift-ci bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 16, 2024
@edsantiago edsantiago force-pushed the package-e2e branch 2 times, most recently from d3b9c75 to 9d25e9e Compare April 16, 2024 23:25
Comment on lines 185 to 195
cwd, _ := os.Getwd()
INTEGRATION_ROOT = filepath.Join(cwd, "../../")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is breaking parallel runs, if you touch these things you should be familiar with how the parallel ginkgo nodes work.
The first function is only run on node 1 while the second one is run on all nodes, so yes this duplication is indeed required here.

One example 5eb99a0

Comment on lines -196 to -206
cwd, _ := os.Getwd()
INTEGRATION_ROOT = filepath.Join(cwd, "../../")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no good to remove, and thanks to ab29ff2 it only needs to happen in one place.

Comment on lines +302 to +311
INTEGRATION_ROOT = os.Getenv("PODMAN_INTEGRATION_ROOT")
if INTEGRATION_ROOT == "" {
cwd, _ := os.Getwd()
INTEGRATION_ROOT = filepath.Join(cwd, "../")
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be set once per node in the second function of SynchronizedBeforeSuite() instead of doing the same logic for every single test

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I totally agree, except, shouldn't that apply to all the settings here in this block also? It's not likely that $PODMAN_REMOTE_BINARY, QUADLET, OCI_RUNTIME, etc will change? May I leave that for a future cleanup?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it is better to leave this for a future cleanup

Copy link
Member

@Luap99 Luap99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we have to distribute these e2e test pre-compiled, I have strong concerns that this will just end up a big maintenance headache. Why exactly must this be an rpm? What is preventing them from checking out the source and using the make target to run the tests?

Comment on lines +287 to +289
# The compiled set of ginkgo tests, and a helper script
install -d -p %{buildroot}/%{_datadir}/%{name}/test/e2e
cp test/e2e/e2e.test hack/podman-registry %{buildroot}/%{_datadir}/%{name}/test/e2e

# Files and subdirectories used by those tests
for testfiles in certs deny.json policy.json redhat_sigstore.yaml registries.conf; do
cp -pav test/$testfiles %{buildroot}/%{_datadir}/%{name}/test/e2e/
done
for subdir in build cdi config quadlet sign testdata; do
cp -pav test/e2e/$subdir %{buildroot}/%{_datadir}/%{name}/test/e2e/
done
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All these spec changes look rather unmaintainable to me. Adding a new file dependencies in different locations will break this easily, sure it shouldn't happen often but there is no way to guarantee that it keeps working.

# Needed for podman-registry script
export PATH=\$PATH:\$PODMAN_INTEGRATION_ROOT

exec ./e2e.test --ginkgo.trace --ginkgo.v "\$@"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

without proper build tags this has low changes of success, or maybe these need to bet set at compile time already?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build tags are set at compile time; I've just pushed a change that should take care of that. I did not understand that yesterday.

@Luap99
Copy link
Member

Luap99 commented Apr 17, 2024

Blue-robot failures look real:

+ ./test/tools/build/ginkgo build test/e2e
Failed to compile e2e:

go build github.com/containers/storage/pkg/devicemapper:
# pkg-config --cflags  -- devmapper
Package devmapper was not found in the pkg-config search path.
Perhaps you should add the directory containing `devmapper.pc'
to the PKG_CONFIG_PATH environment variable
Package 'devmapper', required by 'virtual:world', not found
pkg-config: exit status 1
# github.com/mattn/go-sqlite3
../../vendor/github.com/mattn/go-sqlite3/sqlite3.go:85:1: warning: ‘_sqlite3_exec’ defined but not used [-Wunused-function]
   85 | _sqlite3_exec(sqlite3* db, const char* pcmd, long long* rowid, long long* changes)
      | ^~~~~~~~~~~~~

ginkgo build failed

...but it's not something I'm going to look into today.

MAke sure you are using the proper build tags, devmapper should not be used.

@edsantiago
Copy link
Collaborator Author

Why package these? That's the big question. I'm not completely sold on it; I just want to see if it can be done. And if it can, offer it to the FuSa people and see if they find it useful.

I do believe there is value in test packages that track released packages. For instance, two years from now someone is tracking down a failure in 5.2, installs test rpm on latest Fedora, it fails, that could point to a different component (something else got upgraded, maybe systemd or kernel). With an rpm-maintained test suite, it can be easier to bisect the responsible component. I'm a big fan of bundling tests with builds.

What I really hate is bundling a binary without sources. Yuk. That makes it much harder, probably impossible, for a future maintainer to instrument failing tests. I don't see this as a fixable problem, because Go compilers change so frequently and beyond our control.

Thank you for your feedback!

@Luap99
Copy link
Member

Luap99 commented Apr 18, 2024

I do believe there is value in test packages that track released packages. For instance, two years from now someone is tracking down a failure in 5.2, installs test rpm on latest Fedora, it fails, that could point to a different component (something else got upgraded, maybe systemd or kernel). With an rpm-maintained test suite, it can be easier to bisect the responsible component. I'm a big fan of bundling tests with builds.

Fair but I guess this is where my disconnect is, for me as upstream developer I can just as well checkout v5.2 branch/tag and run the suite that way.

@edsantiago edsantiago force-pushed the package-e2e branch 3 times, most recently from 2489f41 to 184e201 Compare April 22, 2024 14:35
@edsantiago
Copy link
Collaborator Author

rpm-build jobs succeeded. I chased the rabbit down to a page with .repo files, set up the rawhide repo on a VM, and ran:

# dnf install podman-tests podman-remote slirp4netns
...
# /usr/share/podman/test/e2e/run-tests &> /var/tmp/e2e-tests.root.01.log
# echo $?
0    <---- yay!

@edsantiago
Copy link
Collaborator Author

Rootless:

# loginctl enable-linger fedora
# su - fedora
$ /usr/share/podman/test/e2e/run-tests &> /var/tmp/e2e-tests.rootless.01.log
$ echo $?
1
...failed the expected three tests, which I choose not to bother with right now:
Summarizing 3 Failures:
  [FAIL] podman system connection sshd and API services required [It] add ssh:// socket path using connection heuristic
  /builddir/build/BUILD/podman-5.1.0-dev/test/e2e/system_connection_test.go:350
  [FAIL] Podman run with --cgroup-parent [It] no --cgroup-parent
  /builddir/build/BUILD/podman-5.1.0-dev/test/e2e/run_cgroup_parent_test.go:45
  [FAIL] Podman systemd [It] podman run container with systemd PID1
  /builddir/build/BUILD/podman-5.1.0-dev/test/e2e/systemd_test.go:115

# The executables we're testing are the ones delivered in RPM
export PODMAN_BINARY=%{_bindir}/%{name}
export PODMAN_REMOTE_BINARY=%{_bindir}/%{name}-remote
export QUADLET_BINARY=%{_libexecdir}/%{name}/quadlet
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we consider the parameters that related with different releases? Just like the runtime(runc/crun) in different releases? In our rpm testing we also setup NETWORK_BACKEND and OCI_RUNTIME for it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those envariables are evaluated at runtime, so yes, they should work as expected.

@ypu
Copy link
Contributor

ypu commented Apr 26, 2024

This is very helpful for user to run e2e related tests without setup a compile env especially for some env that leak of related packages and resources. But if we want to make sure all tests are passed, there still lots of work to do.

@edsantiago edsantiago force-pushed the package-e2e branch 2 times, most recently from fbb7760 to 445ed42 Compare April 29, 2024 15:15
@edsantiago edsantiago marked this pull request as ready for review April 29, 2024 21:11
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Apr 29, 2024
@edsantiago
Copy link
Collaborator Author

edsantiago commented Apr 29, 2024

@containers/podman-maintainers I think this is ready

[EDIT: this is impossible to review in toto. Please be sure to review commit-by-commit]

Purpose: allow other parties (specifically, FuSa team) to run them.

Exercise turned out to be much more complicated than expected,
so I've broken it into three parts.

Part 1: refactor INTEGRATION_ROOT
 - allow it to be obtained from environment variable.
 - remove triplicate definition
 - redefine it to point one directory level below where it was.
   This allows cleaning up every instance where it was used,
   removing a now-unnecessary "test" directory.

Purpose of this cleanup is allowing e2e tests to be run from
outside the git source tree. The next two commits will move
closer toward that goal.

Signed-off-by: Ed Santiago <santiago@redhat.com>
Part 2: specfile work:
 - add tests/e2e to existing podman-tests package
   - build a static ginkgo test binary
   - copy files needed by tests (registries, certs, build dirs)
   - create a run-tests script, because otherwise it'd be
     impossible for humans to figure out
 - fix tests that were assuming github source tree layout

This commit allows e2e tests to pass as root.

Signed-off-by: Ed Santiago <santiago@redhat.com>
Part 3: get tests passing. Mostly by fixing tests that assume
that cwd is writable. I, um, have taken some liberties in
fixing a couple of broken tests.

Not all tests pass rootless. In particular, these three still fail:

  Podman run with --cgroup-parent [It] no --cgroup-parent
  Podman systemd [It] podman run container with systemd PID1
     -- both with cgroup errors

  podman system connection sshd and API services required [It] add ssh:// socket path using connection heuristic
     -- assumes too much about rootless user's ssh setup

I call this good enough.

Signed-off-by: Ed Santiago <santiago@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. release-note
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants