mirror of
https://github.com/containers/skopeo.git
synced 2025-09-07 09:40:55 +00:00
Add more helpers for running skopeo, use them in existing tests
- consumeAndLogOutputs - assertSkopeoSucceeds - assertSkopeoFails - runCommandWithInput All of these allow running commands as one-liners with no call-site error handling, making tests much more readable. Also modifies TestNoNeedAuthToPrivateRegistryV2ImageNotFound to use check.Matches instead of manual strings.Contains conditions, which is shorter and more consistent with the assertSkopeo... calls.
This commit is contained in:
@@ -3,7 +3,6 @@ package main
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
@@ -15,8 +14,6 @@ const (
|
|||||||
privateRegistryURL2 = "127.0.0.1:5002"
|
privateRegistryURL2 = "127.0.0.1:5002"
|
||||||
privateRegistryURL3 = "127.0.0.1:5003"
|
privateRegistryURL3 = "127.0.0.1:5003"
|
||||||
privateRegistryURL4 = "127.0.0.1:5004"
|
privateRegistryURL4 = "127.0.0.1:5004"
|
||||||
|
|
||||||
skopeoBinary = "skopeo"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
@@ -73,38 +70,26 @@ func (s *SkopeoSuite) TearDownTest(c *check.C) {
|
|||||||
//func skopeoCmd()
|
//func skopeoCmd()
|
||||||
|
|
||||||
func (s *SkopeoSuite) TestVersion(c *check.C) {
|
func (s *SkopeoSuite) TestVersion(c *check.C) {
|
||||||
out, err := exec.Command(skopeoBinary, "--version").CombinedOutput()
|
wanted := fmt.Sprintf(".*%s version .*", skopeoBinary)
|
||||||
c.Assert(err, check.IsNil, check.Commentf(string(out)))
|
assertSkopeoSucceeds(c, wanted, "--version")
|
||||||
wanted := skopeoBinary + " version "
|
|
||||||
if !strings.Contains(string(out), wanted) {
|
|
||||||
c.Fatalf("wanted %s, got %s", wanted, string(out))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
const (
|
||||||
errFetchManifest = "error fetching manifest: status code: %s"
|
errFetchManifestRegexp = ".*error fetching manifest: status code: %s.*"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *SkopeoSuite) TestCanAuthToPrivateRegistryV2WithoutDockerCfg(c *check.C) {
|
func (s *SkopeoSuite) TestCanAuthToPrivateRegistryV2WithoutDockerCfg(c *check.C) {
|
||||||
// TODO(runcom)
|
// TODO(runcom)
|
||||||
c.Skip("we need to restore --username --password flags!")
|
c.Skip("we need to restore --username --password flags!")
|
||||||
out, err := exec.Command(skopeoBinary, "--docker-cfg=''", "--username="+s.regV2WithAuth.username, "--password="+s.regV2WithAuth.password, "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)).CombinedOutput()
|
wanted := fmt.Sprintf(errFetchManifestRegexp, "401")
|
||||||
c.Assert(err, check.NotNil, check.Commentf(string(out)))
|
assertSkopeoFails(c, wanted, "--docker-cfg=''", "--username="+s.regV2WithAuth.username, "--password="+s.regV2WithAuth.password, "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||||
wanted := fmt.Sprintf(errFetchManifest, "401")
|
|
||||||
if !strings.Contains(string(out), wanted) {
|
|
||||||
c.Fatalf("wanted %s, got %s", wanted, string(out))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SkopeoSuite) TestNeedAuthToPrivateRegistryV2WithoutDockerCfg(c *check.C) {
|
func (s *SkopeoSuite) TestNeedAuthToPrivateRegistryV2WithoutDockerCfg(c *check.C) {
|
||||||
// TODO(runcom): mock the empty docker-cfg by removing it in the test itself (?)
|
// TODO(runcom): mock the empty docker-cfg by removing it in the test itself (?)
|
||||||
c.Skip("mock empty docker config")
|
c.Skip("mock empty docker config")
|
||||||
out, err := exec.Command(skopeoBinary, "--docker-cfg=''", "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url)).CombinedOutput()
|
wanted := fmt.Sprintf(errFetchManifestRegexp, "401")
|
||||||
c.Assert(err, check.NotNil, check.Commentf(string(out)))
|
assertSkopeoFails(c, wanted, "--docker-cfg=''", "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2WithAuth.url))
|
||||||
wanted := fmt.Sprintf(errFetchManifest, "401")
|
|
||||||
if !strings.Contains(string(out), wanted) {
|
|
||||||
c.Fatalf("wanted %s, got %s", wanted, string(out))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(runcom): as soon as we can push to registries ensure you can inspect here
|
// TODO(runcom): as soon as we can push to registries ensure you can inspect here
|
||||||
@@ -112,12 +97,8 @@ func (s *SkopeoSuite) TestNeedAuthToPrivateRegistryV2WithoutDockerCfg(c *check.C
|
|||||||
func (s *SkopeoSuite) TestNoNeedAuthToPrivateRegistryV2ImageNotFound(c *check.C) {
|
func (s *SkopeoSuite) TestNoNeedAuthToPrivateRegistryV2ImageNotFound(c *check.C) {
|
||||||
out, err := exec.Command(skopeoBinary, "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2.url)).CombinedOutput()
|
out, err := exec.Command(skopeoBinary, "inspect", fmt.Sprintf("docker://%s/busybox:latest", s.regV2.url)).CombinedOutput()
|
||||||
c.Assert(err, check.NotNil, check.Commentf(string(out)))
|
c.Assert(err, check.NotNil, check.Commentf(string(out)))
|
||||||
wanted := fmt.Sprintf(errFetchManifest, "404")
|
wanted := fmt.Sprintf(errFetchManifestRegexp, "404")
|
||||||
if !strings.Contains(string(out), wanted) {
|
c.Assert(string(out), check.Matches, "(?s)"+wanted) // (?s) : '.' will also match newlines
|
||||||
c.Fatalf("wanted %s, got %s", wanted, string(out))
|
wanted = fmt.Sprintf(errFetchManifestRegexp, "401")
|
||||||
}
|
c.Assert(string(out), check.Not(check.Matches), "(?s)"+wanted) // (?s) : '.' will also match newlines
|
||||||
wanted = fmt.Sprintf(errFetchManifest, "401")
|
|
||||||
if strings.Contains(string(out), wanted) {
|
|
||||||
c.Fatalf("not wanted %s, got %s", wanted, string(out))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
@@ -42,21 +43,7 @@ func (s *SigningSuite) SetUpTest(c *check.C) {
|
|||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
os.Setenv("GNUPGHOME", s.gpgHome)
|
os.Setenv("GNUPGHOME", s.gpgHome)
|
||||||
|
|
||||||
cmd := exec.Command(gpgBinary, "--homedir", s.gpgHome, "--batch", "--gen-key")
|
runCommandWithInput(c, "Key-Type: RSA\nName-Real: Testing user\n%commit\n", gpgBinary, "--homedir", s.gpgHome, "--batch", "--gen-key")
|
||||||
stdin, err := cmd.StdinPipe()
|
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
stdout, err := cmd.StdoutPipe()
|
|
||||||
consumeAndLogOutput(c, "gen-key stdout", stdout, err)
|
|
||||||
stderr, err := cmd.StderrPipe()
|
|
||||||
consumeAndLogOutput(c, "gen-key stderr", stderr, err)
|
|
||||||
err = cmd.Start()
|
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
_, err = stdin.Write([]byte("Key-Type: RSA\nName-Real: Testing user\n%commit\n"))
|
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
err = stdin.Close()
|
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
err = cmd.Wait()
|
|
||||||
c.Assert(err, check.IsNil)
|
|
||||||
|
|
||||||
lines, err := exec.Command(gpgBinary, "--homedir", s.gpgHome, "--with-colons", "--no-permission-warning", "--fingerprint").Output()
|
lines, err := exec.Command(gpgBinary, "--homedir", s.gpgHome, "--with-colons", "--no-permission-warning", "--fingerprint").Output()
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
@@ -81,13 +68,10 @@ func (s *SigningSuite) TestSignVerifySmoke(c *check.C) {
|
|||||||
sigOutput, err := ioutil.TempFile("", "sig")
|
sigOutput, err := ioutil.TempFile("", "sig")
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
defer os.Remove(sigOutput.Name())
|
defer os.Remove(sigOutput.Name())
|
||||||
out, err := exec.Command(skopeoBinary, "standalone-sign", "-o", sigOutput.Name(),
|
assertSkopeoSucceeds(c, "^$", "standalone-sign", "-o", sigOutput.Name(),
|
||||||
manifestPath, dockerReference, s.fingerprint).CombinedOutput()
|
manifestPath, dockerReference, s.fingerprint)
|
||||||
c.Assert(err, check.IsNil, check.Commentf("%s", out))
|
|
||||||
c.Assert(string(out), check.Equals, "")
|
|
||||||
|
|
||||||
out, err = exec.Command(skopeoBinary, "standalone-verify", manifestPath,
|
expected := fmt.Sprintf("^Signature verified, digest %s\n$", TestImageManifestDigest)
|
||||||
dockerReference, s.fingerprint, sigOutput.Name()).CombinedOutput()
|
assertSkopeoSucceeds(c, expected, "standalone-verify", manifestPath,
|
||||||
c.Assert(err, check.IsNil, check.Commentf("%s", out))
|
dockerReference, s.fingerprint, sigOutput.Name())
|
||||||
c.Assert(string(out), check.Equals, "Signature verified, digest "+TestImageManifestDigest+"\n")
|
|
||||||
}
|
}
|
||||||
|
@@ -2,13 +2,16 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/go-check/check"
|
"github.com/go-check/check"
|
||||||
)
|
)
|
||||||
|
|
||||||
// consumeAndLogOutput takes (f, err) from an exec.*Pipe(), and causes all output to it to be logged to c.
|
const skopeoBinary = "skopeo"
|
||||||
func consumeAndLogOutput(c *check.C, id string, f io.ReadCloser, err error) {
|
|
||||||
|
// consumeAndLogOutputStream takes (f, err) from an exec.*Pipe(), and causes all output to it to be logged to c.
|
||||||
|
func consumeAndLogOutputStream(c *check.C, id string, f io.ReadCloser, err error) {
|
||||||
c.Assert(err, check.IsNil)
|
c.Assert(err, check.IsNil)
|
||||||
go func() {
|
go func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
@@ -26,3 +29,51 @@ func consumeAndLogOutput(c *check.C, id string, f io.ReadCloser, err error) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// consumeAndLogOutputs causes all output to stdout and stderr from an *exec.Cmd to be logged to c
|
||||||
|
func consumeAndLogOutputs(c *check.C, id string, cmd *exec.Cmd) {
|
||||||
|
stdout, err := cmd.StdoutPipe()
|
||||||
|
consumeAndLogOutputStream(c, id+" stdout", stdout, err)
|
||||||
|
stderr, err := cmd.StderrPipe()
|
||||||
|
consumeAndLogOutputStream(c, id+" stderr", stderr, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertSkopeoSucceeds runs a skopeo command as if exec.Command().CombinedOutput, verifies that the exit status is 0,
|
||||||
|
// and optionally that the output matches a multi-line regexp if it is nonempty;
|
||||||
|
// or terminates c on failure
|
||||||
|
func assertSkopeoSucceeds(c *check.C, regexp string, args ...string) {
|
||||||
|
c.Logf("Running %s %s", skopeoBinary, strings.Join(args, " "))
|
||||||
|
out, err := exec.Command(skopeoBinary, args...).CombinedOutput()
|
||||||
|
c.Assert(err, check.IsNil, check.Commentf("%s", out))
|
||||||
|
if regexp != "" {
|
||||||
|
c.Assert(string(out), check.Matches, "(?s)"+regexp) // (?s) : '.' will also match newlines
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assertSkopeoFails runs a skopeo command as if exec.Command().CombinedOutput, verifies that the exit status is 0,
|
||||||
|
// and that the output matches a multi-line regexp;
|
||||||
|
// or terminates c on failure
|
||||||
|
func assertSkopeoFails(c *check.C, regexp string, args ...string) {
|
||||||
|
c.Logf("Running %s %s", skopeoBinary, strings.Join(args, " "))
|
||||||
|
out, err := exec.Command(skopeoBinary, args...).CombinedOutput()
|
||||||
|
c.Assert(err, check.NotNil, check.Commentf("%s", out))
|
||||||
|
c.Assert(string(out), check.Matches, "(?s)"+regexp) // (?s) : '.' will also match newlines
|
||||||
|
}
|
||||||
|
|
||||||
|
// runCommandWithInput runs a command as if exec.Command(), sending it the input to stdin,
|
||||||
|
// and verifies that the exit status is 0, or terminates c on failure.
|
||||||
|
func runCommandWithInput(c *check.C, input string, name string, args ...string) {
|
||||||
|
c.Logf("Running %s %s", name, strings.Join(args, " "))
|
||||||
|
cmd := exec.Command(name, args...)
|
||||||
|
consumeAndLogOutputs(c, name+" "+strings.Join(args, " "), cmd)
|
||||||
|
stdin, err := cmd.StdinPipe()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
err = cmd.Start()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
_, err = stdin.Write([]byte(input))
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
err = stdin.Close()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
err = cmd.Wait()
|
||||||
|
c.Assert(err, check.IsNil)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user