summaryrefslogtreecommitdiff
path: root/test/e2e/libpod_suite_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'test/e2e/libpod_suite_test.go')
-rw-r--r--test/e2e/libpod_suite_test.go308
1 files changed, 308 insertions, 0 deletions
diff --git a/test/e2e/libpod_suite_test.go b/test/e2e/libpod_suite_test.go
new file mode 100644
index 000000000..2f541244c
--- /dev/null
+++ b/test/e2e/libpod_suite_test.go
@@ -0,0 +1,308 @@
+package integration
+
+import (
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/exec"
+ "path/filepath"
+ "strings"
+ "testing"
+
+ "github.com/containers/image/copy"
+ "github.com/containers/image/signature"
+ "github.com/containers/image/storage"
+ "github.com/containers/image/transports/alltransports"
+ "github.com/containers/image/types"
+ sstorage "github.com/containers/storage"
+ "github.com/containers/storage/pkg/reexec"
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "github.com/onsi/gomega/gexec"
+ "github.com/pkg/errors"
+)
+
+// - CRIO_ROOT=/var/tmp/checkout PODMAN_BINARY=/usr/bin/podman CONMON_BINARY=/usr/libexec/crio/conmon PAPR=1 sh .papr.sh
+// PODMAN_OPTIONS="--root $TESTDIR/crio $STORAGE_OPTIONS --runroot $TESTDIR/crio-run --runtime ${RUNTIME_BINARY} --conmon ${CONMON_BINARY} --cni-config-dir ${LIBPOD_CNI_CONFIG}"
+
+//TODO do the image caching
+// "$COPYIMG_BINARY" --root "$TESTDIR/crio" $STORAGE_OPTIONS --runroot "$TESTDIR/crio-run" --image-name=${IMAGES[${key}]} --import-from=dir:"$ARTIFACTS_PATH"/${key} --add-name=${IMAGES[${key}]}
+//TODO whats the best way to clean up after a test
+
+var (
+ PODMAN_BINARY string
+ CONMON_BINARY string
+ CNI_CONFIG_DIR string
+ RUNC_BINARY string
+ INTEGRATION_ROOT string
+ STORAGE_OPTIONS = "--storage-driver vfs"
+ ARTIFACT_DIR = "/tmp/.artifacts"
+ IMAGES = []string{"alpine", "busybox"}
+ ALPINE = "docker.io/library/alpine:latest"
+ BB_GLIBC = "docker.io/library/busybox:glibc"
+ fedoraMinimal = "registry.fedoraproject.org/fedora-minimal:latest"
+)
+
+// PodmanSession wrapps the gexec.session so we can extend it
+type PodmanSession struct {
+ *gexec.Session
+}
+
+// PodmanTest struct for command line options
+type PodmanTest struct {
+ PodmanBinary string
+ ConmonBinary string
+ CrioRoot string
+ CNIConfigDir string
+ RunCBinary string
+ RunRoot string
+ StorageOptions string
+ SignaturePolicyPath string
+ ArtifactPath string
+ TempDir string
+}
+
+// TestLibpod ginkgo master function
+func TestLibpod(t *testing.T) {
+ if reexec.Init() {
+ os.Exit(1)
+ }
+ RegisterFailHandler(Fail)
+ RunSpecs(t, "Libpod Suite")
+}
+
+var _ = BeforeSuite(func() {
+ //Cache images
+ cwd, _ := os.Getwd()
+ INTEGRATION_ROOT = filepath.Join(cwd, "../../")
+ podman := PodmanCreate("/tmp")
+ podman.ArtifactPath = ARTIFACT_DIR
+ if _, err := os.Stat(ARTIFACT_DIR); os.IsNotExist(err) {
+ if err = os.Mkdir(ARTIFACT_DIR, 0777); err != nil {
+ fmt.Printf("%q\n", err)
+ os.Exit(1)
+ }
+ }
+ for _, image := range IMAGES {
+ fmt.Printf("Caching %s...\n", image)
+ if err := podman.CreateArtifact(image); err != nil {
+ fmt.Printf("%q\n", err)
+ os.Exit(1)
+ }
+ }
+
+})
+
+// CreateTempDirin
+func CreateTempDirInTempDir() (string, error) {
+ return ioutil.TempDir("", "podman_test")
+}
+
+// PodmanCreate creates a PodmanTest instance for the tests
+func PodmanCreate(tempDir string) PodmanTest {
+ cwd, _ := os.Getwd()
+
+ podmanBinary := filepath.Join(cwd, "../../bin/podman")
+ if os.Getenv("PODMAN_BINARY") != "" {
+ podmanBinary = os.Getenv("PODMAN_BINARY")
+ }
+ conmonBinary := filepath.Join("/usr/libexec/crio/conmon")
+ if os.Getenv("CONMON_BINARY") != "" {
+ conmonBinary = os.Getenv("CONMON_BINARY")
+ }
+ storageOptions := STORAGE_OPTIONS
+ if os.Getenv("STORAGE_OPTIONS") != "" {
+ storageOptions = os.Getenv("STORAGE_OPTIONS")
+ }
+
+ runCBinary := "/usr/bin/runc"
+ CNIConfigDir := "/etc/cni/net.d"
+
+ return PodmanTest{
+ PodmanBinary: podmanBinary,
+ ConmonBinary: conmonBinary,
+ CrioRoot: filepath.Join(tempDir, "crio"),
+ CNIConfigDir: CNIConfigDir,
+ RunCBinary: runCBinary,
+ RunRoot: filepath.Join(tempDir, "crio-run"),
+ StorageOptions: storageOptions,
+ SignaturePolicyPath: filepath.Join(INTEGRATION_ROOT, "test/policy.json"),
+ ArtifactPath: ARTIFACT_DIR,
+ TempDir: tempDir,
+ }
+}
+
+//MakeOptions assembles all the podman main options
+func (p *PodmanTest) MakeOptions() []string {
+ return strings.Split(fmt.Sprintf("--root %s --runroot %s --runtime %s --conmon %s --cni-config-dir %s",
+ p.CrioRoot, p.RunRoot, p.RunCBinary, p.ConmonBinary, p.CNIConfigDir), " ")
+}
+
+// Podman is the exec call to podman on the filesystem
+func (p *PodmanTest) Podman(args []string) *PodmanSession {
+ podmanOptions := p.MakeOptions()
+ podmanOptions = append(podmanOptions, strings.Split(p.StorageOptions, " ")...)
+ podmanOptions = append(podmanOptions, args...)
+ fmt.Printf("Running: %s %s\n", p.PodmanBinary, strings.Join(podmanOptions, " "))
+ command := exec.Command(p.PodmanBinary, podmanOptions...)
+ session, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
+ if err != nil {
+ Fail(fmt.Sprintf("unable to run podman command: %s", strings.Join(podmanOptions, " ")))
+ }
+ return &PodmanSession{session}
+}
+
+// Cleanup cleans up the temporary store
+func (p *PodmanTest) Cleanup() {
+ // Remove all containers
+ session := p.Podman([]string{"rm", "-fa"})
+ session.Wait()
+ // Nuke tempdir
+ if err := os.RemoveAll(p.TempDir); err != nil {
+ fmt.Printf("%q\n", err)
+ }
+}
+
+// GrepString takes session output and behaves like grep. it returns a bool
+// if successful and an array of strings on positive matches
+func (s *PodmanSession) GrepString(term string) (bool, []string) {
+ var (
+ greps []string
+ matches bool
+ )
+
+ for _, line := range strings.Split(s.OutputToString(), "\n") {
+ if strings.Contains(line, term) {
+ matches = true
+ greps = append(greps, line)
+ }
+ }
+ return matches, greps
+}
+
+// Pull Images pulls multiple images
+func (p *PodmanTest) PullImages(images []string) error {
+ for _, i := range images {
+ p.PullImage(i)
+ }
+ return nil
+}
+
+// Pull Image a single image
+// TODO should the timeout be configurable?
+func (p *PodmanTest) PullImage(image string) error {
+ session := p.Podman([]string{"pull", image})
+ session.Wait(60)
+ Expect(session.ExitCode()).To(Equal(0))
+ return nil
+}
+
+// OutputToString formats session output to string
+func (s *PodmanSession) OutputToString() string {
+ fields := strings.Fields(fmt.Sprintf("%s", s.Out.Contents()))
+ return strings.Join(fields, " ")
+}
+
+// SystemExec is used to exec a system command to check its exit code or output
+func (p *PodmanTest) SystemExec(command string, args []string) *PodmanSession {
+ c := exec.Command(command, args...)
+ session, err := gexec.Start(c, GinkgoWriter, GinkgoWriter)
+ if err != nil {
+ Fail(fmt.Sprintf("unable to run command: %s %s", command, strings.Join(args, " ")))
+ }
+ return &PodmanSession{session}
+}
+
+// CreateArtifact creates a cached image in the artifact dir
+func (p *PodmanTest) CreateArtifact(image string) error {
+ imageName := fmt.Sprintf("docker://%s", image)
+ systemContext := types.SystemContext{
+ SignaturePolicyPath: p.SignaturePolicyPath,
+ }
+ policy, err := signature.DefaultPolicy(&systemContext)
+ if err != nil {
+ return errors.Errorf("error loading signature policy: %v", err)
+ }
+ policyContext, err := signature.NewPolicyContext(policy)
+ if err != nil {
+ return errors.Errorf("error loading signature policy: %v", err)
+ }
+ defer func() {
+ _ = policyContext.Destroy()
+ }()
+ options := &copy.Options{}
+
+ importRef, err := alltransports.ParseImageName(imageName)
+ if err != nil {
+ return errors.Errorf("error parsing image name %v: %v", image, err)
+ }
+
+ exportTo := filepath.Join("dir:", p.ArtifactPath, image)
+ exportRef, err := alltransports.ParseImageName(exportTo)
+ if err != nil {
+ return errors.Errorf("error parsing image name %v: %v", exportTo, err)
+ }
+
+ return copy.Image(policyContext, exportRef, importRef, options)
+
+ return nil
+}
+
+// RestoreArtifact puts the cached image into our test store
+func (p *PodmanTest) RestoreArtifact(image string) error {
+ storeOptions := sstorage.DefaultStoreOptions
+ storeOptions.GraphDriverName = "vfs"
+ //storeOptions.GraphDriverOptions = storageOptions
+ storeOptions.GraphRoot = p.CrioRoot
+ storeOptions.RunRoot = p.RunRoot
+ store, err := sstorage.GetStore(storeOptions)
+
+ options := &copy.Options{}
+ if err != nil {
+ return errors.Errorf("error opening storage: %v", err)
+ }
+ defer func() {
+ _, _ = store.Shutdown(false)
+ }()
+
+ storage.Transport.SetStore(store)
+ ref, err := storage.Transport.ParseStoreReference(store, image)
+ if err != nil {
+ return errors.Errorf("error parsing image name: %v", err)
+ }
+
+ importFrom := fmt.Sprintf("dir:%s", filepath.Join(p.ArtifactPath, image))
+ importRef, err := alltransports.ParseImageName(importFrom)
+ if err != nil {
+ return errors.Errorf("error parsing image name %v: %v", image, err)
+ }
+ systemContext := types.SystemContext{
+ SignaturePolicyPath: p.SignaturePolicyPath,
+ }
+ policy, err := signature.DefaultPolicy(&systemContext)
+ if err != nil {
+ return errors.Errorf("error loading signature policy: %v", err)
+ }
+ policyContext, err := signature.NewPolicyContext(policy)
+ if err != nil {
+ return errors.Errorf("error loading signature policy: %v", err)
+ }
+ defer func() {
+ _ = policyContext.Destroy()
+ }()
+ err = copy.Image(policyContext, ref, importRef, options)
+ if err != nil {
+ return errors.Errorf("error importing %s: %v", importFrom, err)
+ }
+ return nil
+}
+
+// RestoreAllArtifacts unpacks all cached images
+func (p *PodmanTest) RestoreAllArtifacts() error {
+ for _, image := range IMAGES {
+ if err := p.RestoreArtifact(image); err != nil {
+ return err
+ }
+ }
+ return nil
+}