1
0
Fork 0
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:
Vincent Demeester 2018-04-13 10:45:34 +02:00
parent 544ec0994f
commit 66de2e6e3b
No known key found for this signature in database
GPG key ID: 083CC6FD6EB699A3
10 changed files with 119 additions and 81 deletions

View file

@ -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()

View file

@ -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")

View file

@ -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"
)

View file

@ -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"
)

View file

@ -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.

View file

@ -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
}

View file

@ -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) {

View 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
}
}

View file

@ -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)
}

View file

@ -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"