mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Move and refactor integration-cli/registry to internal/test
- Move the code from `integration-cli` to `internal/test`. - Use `testingT` and `assert` when creating the registry. Signed-off-by: Vincent Demeester <vincent@sbr.pm>
This commit is contained in:
parent
544ec0994f
commit
66de2e6e3b
10 changed files with 119 additions and 81 deletions
|
@ -20,9 +20,9 @@ import (
|
|||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/environment"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
"github.com/docker/docker/integration-cli/registry"
|
||||
testdaemon "github.com/docker/docker/internal/test/daemon"
|
||||
ienv "github.com/docker/docker/internal/test/environment"
|
||||
"github.com/docker/docker/internal/test/registry"
|
||||
"github.com/docker/docker/pkg/reexec"
|
||||
"github.com/go-check/check"
|
||||
"golang.org/x/net/context"
|
||||
|
@ -30,7 +30,7 @@ import (
|
|||
|
||||
const (
|
||||
// the private registry to use for tests
|
||||
privateRegistryURL = "127.0.0.1:5000"
|
||||
privateRegistryURL = registry.DefaultURL
|
||||
|
||||
// path to containerd's ctr binary
|
||||
ctrBinary = "docker-containerd-ctr"
|
||||
|
@ -126,8 +126,9 @@ func (s *DockerRegistrySuite) OnTimeout(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
|
||||
s.reg = setupRegistry(c, false, "", "")
|
||||
testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
|
||||
s.reg = registry.NewV2(c)
|
||||
s.reg.WaitReady(c)
|
||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
})
|
||||
|
@ -160,8 +161,9 @@ func (s *DockerSchema1RegistrySuite) OnTimeout(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, registry.Hosting, NotArm64, SameHostDaemon)
|
||||
s.reg = setupRegistry(c, true, "", "")
|
||||
testRequires(c, DaemonIsLinux, RegistryHosting, NotArm64, SameHostDaemon)
|
||||
s.reg = registry.NewV2(c, registry.Schema1)
|
||||
s.reg.WaitReady(c)
|
||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
})
|
||||
|
@ -194,8 +196,9 @@ func (s *DockerRegistryAuthHtpasswdSuite) OnTimeout(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *DockerRegistryAuthHtpasswdSuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
|
||||
s.reg = setupRegistry(c, false, "htpasswd", "")
|
||||
testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
|
||||
s.reg = registry.NewV2(c, registry.Htpasswd)
|
||||
s.reg.WaitReady(c)
|
||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
})
|
||||
|
@ -230,7 +233,7 @@ func (s *DockerRegistryAuthTokenSuite) OnTimeout(c *check.C) {
|
|||
}
|
||||
|
||||
func (s *DockerRegistryAuthTokenSuite) SetUpTest(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, registry.Hosting, SameHostDaemon)
|
||||
testRequires(c, DaemonIsLinux, RegistryHosting, SameHostDaemon)
|
||||
s.d = daemon.New(c, dockerBinary, dockerdBinary, daemon.Config{
|
||||
Experimental: testEnv.DaemonInfo.ExperimentalBuild,
|
||||
})
|
||||
|
@ -252,7 +255,8 @@ func (s *DockerRegistryAuthTokenSuite) setupRegistryWithTokenService(c *check.C,
|
|||
if s == nil {
|
||||
c.Fatal("registry suite isn't initialized")
|
||||
}
|
||||
s.reg = setupRegistry(c, false, "token", tokenURL)
|
||||
s.reg = registry.NewV2(c, registry.Token(tokenURL))
|
||||
s.reg.WaitReady(c)
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
@ -405,8 +409,9 @@ func (ps *DockerPluginSuite) getPluginRepoWithTag() string {
|
|||
}
|
||||
|
||||
func (ps *DockerPluginSuite) SetUpSuite(c *check.C) {
|
||||
testRequires(c, DaemonIsLinux, registry.Hosting)
|
||||
ps.registry = setupRegistry(c, false, "", "")
|
||||
testRequires(c, DaemonIsLinux, RegistryHosting)
|
||||
ps.registry = registry.NewV2(c)
|
||||
ps.registry.WaitReady(c)
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||||
defer cancel()
|
||||
|
|
|
@ -16,6 +16,7 @@ import (
|
|||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/fixtures/plugin"
|
||||
testdaemon "github.com/docker/docker/internal/test/daemon"
|
||||
"github.com/docker/docker/internal/test/registry"
|
||||
"github.com/go-check/check"
|
||||
"golang.org/x/net/context"
|
||||
"golang.org/x/sys/unix"
|
||||
|
@ -615,7 +616,7 @@ func (s *DockerSwarmSuite) TestAPISwarmServicesStateReporting(c *check.C) {
|
|||
func (s *DockerSwarmSuite) TestAPISwarmServicesPlugin(c *check.C) {
|
||||
testRequires(c, ExperimentalDaemon, DaemonIsLinux, IsAmd64)
|
||||
|
||||
reg := setupRegistry(c, false, "", "")
|
||||
reg := registry.NewV2(c)
|
||||
defer reg.Close()
|
||||
|
||||
repo := path.Join(privateRegistryURL, "swarm", "test:v1")
|
||||
|
|
|
@ -7,7 +7,7 @@ import (
|
|||
"os"
|
||||
"regexp"
|
||||
|
||||
"github.com/docker/docker/integration-cli/registry"
|
||||
"github.com/docker/docker/internal/test/registry"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/docker/docker/integration-cli/registry"
|
||||
"github.com/docker/docker/internal/test/registry"
|
||||
"github.com/go-check/check"
|
||||
)
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/docker/docker/integration-cli/checker"
|
||||
"github.com/docker/docker/integration-cli/cli"
|
||||
"github.com/docker/docker/integration-cli/daemon"
|
||||
"github.com/docker/docker/integration-cli/registry"
|
||||
"github.com/docker/docker/integration-cli/request"
|
||||
"github.com/go-check/check"
|
||||
"github.com/gotestyourself/gotestyourself/icmd"
|
||||
|
@ -284,22 +283,6 @@ func parseEventTime(t time.Time) string {
|
|||
return fmt.Sprintf("%d.%09d", t.Unix(), int64(t.Nanosecond()))
|
||||
}
|
||||
|
||||
func setupRegistry(c *check.C, schema1 bool, auth, tokenURL string) *registry.V2 {
|
||||
reg, err := registry.NewV2(schema1, auth, tokenURL, privateRegistryURL)
|
||||
c.Assert(err, check.IsNil)
|
||||
|
||||
// Wait for registry to be ready to serve requests.
|
||||
for i := 0; i != 50; i++ {
|
||||
if err = reg.Ping(); err == nil {
|
||||
break
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
c.Assert(err, check.IsNil, check.Commentf("Timeout waiting for test registry to become available: %v", err))
|
||||
return reg
|
||||
}
|
||||
|
||||
// appendBaseEnv appends the minimum set of environment variables to exec the
|
||||
// docker cli binary for testing with correct configuration to the given env
|
||||
// list.
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
package registry // import "github.com/docker/docker/integration-cli/registry"
|
||||
|
||||
import "os/exec"
|
||||
|
||||
// Hosting returns wether the host can host a registry (v2) or not
|
||||
func Hosting() bool {
|
||||
// for now registry binary is built only if we're running inside
|
||||
// container through `make test`. Figure that out by testing if
|
||||
// registry binary is in PATH.
|
||||
_, err := exec.LookPath(v2binary)
|
||||
return err == nil
|
||||
}
|
|
@ -14,6 +14,7 @@ import (
|
|||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/integration-cli/requirement"
|
||||
"github.com/docker/docker/internal/test/registry"
|
||||
)
|
||||
|
||||
func ArchitectureIsNot(arch string) bool {
|
||||
|
@ -183,6 +184,15 @@ func IsolationIsProcess() bool {
|
|||
return IsolationIs("process")
|
||||
}
|
||||
|
||||
// RegistryHosting returns wether the host can host a registry (v2) or not
|
||||
func RegistryHosting() bool {
|
||||
// for now registry binary is built only if we're running inside
|
||||
// container through `make test`. Figure that out by testing if
|
||||
// registry binary is in PATH.
|
||||
_, err := exec.LookPath(registry.V2binary)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// testRequires checks if the environment satisfies the requirements
|
||||
// for the test to run or skips the tests.
|
||||
func testRequires(c requirement.SkipT, requirements ...requirement.Test) {
|
||||
|
|
26
internal/test/registry/ops.go
Normal file
26
internal/test/registry/ops.go
Normal file
|
@ -0,0 +1,26 @@
|
|||
package registry
|
||||
|
||||
// Schema1 sets the registry to serve v1 api
|
||||
func Schema1(c *Config) {
|
||||
c.schema1 = true
|
||||
}
|
||||
|
||||
// Htpasswd sets the auth method with htpasswd
|
||||
func Htpasswd(c *Config) {
|
||||
c.auth = "htpasswd"
|
||||
}
|
||||
|
||||
// Token sets the auth method to token, with the specified token url
|
||||
func Token(tokenURL string) func(*Config) {
|
||||
return func(c *Config) {
|
||||
c.auth = "token"
|
||||
c.tokenURL = tokenURL
|
||||
}
|
||||
}
|
||||
|
||||
// URL sets the registry url
|
||||
func URL(registryURL string) func(*Config) {
|
||||
return func(c *Config) {
|
||||
c.registryURL = registryURL
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package registry // import "github.com/docker/docker/integration-cli/registry"
|
||||
package registry // import "github.com/docker/docker/internal/test/registry"
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
@ -7,16 +7,23 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gotestyourself/gotestyourself/assert"
|
||||
"github.com/opencontainers/go-digest"
|
||||
)
|
||||
|
||||
const (
|
||||
v2binary = "registry-v2"
|
||||
v2binarySchema1 = "registry-v2-schema1"
|
||||
// V2binary is the name of the registry v2 binary
|
||||
V2binary = "registry-v2"
|
||||
// V2binarySchema1 is the name of the registry that serve schema1
|
||||
V2binarySchema1 = "registry-v2-schema1"
|
||||
// DefaultURL is the default url that will be used by the registry (if not specified otherwise)
|
||||
DefaultURL = "127.0.0.1:5000"
|
||||
)
|
||||
|
||||
type testingT interface {
|
||||
assert.TestingT
|
||||
logT
|
||||
Fatal(...interface{})
|
||||
Fatalf(string, ...interface{})
|
||||
|
@ -37,12 +44,24 @@ type V2 struct {
|
|||
email string
|
||||
}
|
||||
|
||||
// Config contains the test registry configuration
|
||||
type Config struct {
|
||||
schema1 bool
|
||||
auth string
|
||||
tokenURL string
|
||||
registryURL string
|
||||
}
|
||||
|
||||
// NewV2 creates a v2 registry server
|
||||
func NewV2(schema1 bool, auth, tokenURL, registryURL string) (*V2, error) {
|
||||
tmp, err := ioutil.TempDir("", "registry-test-")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func NewV2(t testingT, ops ...func(*Config)) *V2 {
|
||||
c := &Config{
|
||||
registryURL: DefaultURL,
|
||||
}
|
||||
for _, op := range ops {
|
||||
op(c)
|
||||
}
|
||||
tmp, err := ioutil.TempDir("", "registry-test-")
|
||||
assert.NilError(t, err)
|
||||
template := `version: 0.1
|
||||
loglevel: debug
|
||||
storage:
|
||||
|
@ -57,7 +76,7 @@ http:
|
|||
password string
|
||||
email string
|
||||
)
|
||||
switch auth {
|
||||
switch c.auth {
|
||||
case "htpasswd":
|
||||
htpasswdPath := filepath.Join(tmp, "htpasswd")
|
||||
// generated with: htpasswd -Bbn testuser testpassword
|
||||
|
@ -65,9 +84,8 @@ http:
|
|||
username = "testuser"
|
||||
password = "testpassword"
|
||||
email = "test@test.org"
|
||||
if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644))
|
||||
assert.NilError(t, err)
|
||||
authTemplate = fmt.Sprintf(`auth:
|
||||
htpasswd:
|
||||
realm: basic-realm
|
||||
|
@ -80,39 +98,51 @@ http:
|
|||
service: "registry"
|
||||
issuer: "auth-registry"
|
||||
rootcertbundle: "fixtures/registry/cert.pem"
|
||||
`, tokenURL)
|
||||
`, c.tokenURL)
|
||||
}
|
||||
|
||||
confPath := filepath.Join(tmp, "config.yaml")
|
||||
config, err := os.Create(confPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
assert.NilError(t, err)
|
||||
defer config.Close()
|
||||
|
||||
if _, err := fmt.Fprintf(config, template, tmp, registryURL, authTemplate); err != nil {
|
||||
if _, err := fmt.Fprintf(config, template, tmp, c.registryURL, authTemplate); err != nil {
|
||||
// FIXME(vdemeester) use a defer/clean func
|
||||
os.RemoveAll(tmp)
|
||||
return nil, err
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
binary := v2binary
|
||||
if schema1 {
|
||||
binary = v2binarySchema1
|
||||
binary := V2binary
|
||||
if c.schema1 {
|
||||
binary = V2binarySchema1
|
||||
}
|
||||
cmd := exec.Command(binary, confPath)
|
||||
if err := cmd.Start(); err != nil {
|
||||
// FIXME(vdemeester) use a defer/clean func
|
||||
os.RemoveAll(tmp)
|
||||
return nil, err
|
||||
t.Fatal(err)
|
||||
}
|
||||
return &V2{
|
||||
cmd: cmd,
|
||||
dir: tmp,
|
||||
auth: auth,
|
||||
auth: c.auth,
|
||||
username: username,
|
||||
password: password,
|
||||
email: email,
|
||||
registryURL: registryURL,
|
||||
}, nil
|
||||
registryURL: c.registryURL,
|
||||
}
|
||||
}
|
||||
|
||||
// WaitReady waits for the registry to be ready to serve requests (or fail after a while)
|
||||
func (r *V2) WaitReady(t testingT) {
|
||||
var err error
|
||||
for i := 0; i != 50; i++ {
|
||||
if err = r.Ping(); err == nil {
|
||||
return
|
||||
}
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
t.Fatalf("timeout waiting for test registry to become available: %v", err)
|
||||
}
|
||||
|
||||
// Ping sends an http request to the current registry, and fail if it doesn't respond correctly
|
||||
|
@ -152,30 +182,24 @@ func (r *V2) getBlobFilename(blobDigest digest.Digest) string {
|
|||
}
|
||||
|
||||
// ReadBlobContents read the file corresponding to the specified digest
|
||||
func (r *V2) ReadBlobContents(t testingT, blobDigest digest.Digest) []byte {
|
||||
func (r *V2) ReadBlobContents(t assert.TestingT, blobDigest digest.Digest) []byte {
|
||||
// Load the target manifest blob.
|
||||
manifestBlob, err := ioutil.ReadFile(r.getBlobFilename(blobDigest))
|
||||
if err != nil {
|
||||
t.Fatalf("unable to read blob: %s", err)
|
||||
}
|
||||
|
||||
assert.NilError(t, err, "unable to read blob")
|
||||
return manifestBlob
|
||||
}
|
||||
|
||||
// WriteBlobContents write the file corresponding to the specified digest with the given content
|
||||
func (r *V2) WriteBlobContents(t testingT, blobDigest digest.Digest, data []byte) {
|
||||
if err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644)); err != nil {
|
||||
t.Fatalf("unable to write malicious data blob: %s", err)
|
||||
}
|
||||
func (r *V2) WriteBlobContents(t assert.TestingT, blobDigest digest.Digest, data []byte) {
|
||||
err := ioutil.WriteFile(r.getBlobFilename(blobDigest), data, os.FileMode(0644))
|
||||
assert.NilError(t, err, "unable to write malicious data blob")
|
||||
}
|
||||
|
||||
// TempMoveBlobData moves the existing data file aside, so that we can replace it with a
|
||||
// malicious blob of data for example.
|
||||
func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func()) {
|
||||
tempFile, err := ioutil.TempFile("", "registry-temp-blob-")
|
||||
if err != nil {
|
||||
t.Fatalf("unable to get temporary blob file: %s", err)
|
||||
}
|
||||
assert.NilError(t, err, "unable to get temporary blob file")
|
||||
tempFile.Close()
|
||||
|
||||
blobFilename := r.getBlobFilename(blobDigest)
|
||||
|
@ -183,6 +207,7 @@ func (r *V2) TempMoveBlobData(t testingT, blobDigest digest.Digest) (undo func()
|
|||
// Move the existing data file aside, so that we can replace it with a
|
||||
// another blob of data.
|
||||
if err := os.Rename(blobFilename, tempFile.Name()); err != nil {
|
||||
// FIXME(vdemeester) use a defer/clean func
|
||||
os.Remove(tempFile.Name())
|
||||
t.Fatalf("unable to move data blob: %s", err)
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package registry // import "github.com/docker/docker/integration-cli/registry"
|
||||
package registry // import "github.com/docker/docker/internal/test/registry"
|
||||
|
||||
import (
|
||||
"net/http"
|
Loading…
Reference in a new issue