integration-cli: add suite for testing registries with auth

Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
Antonio Murdaca 2016-01-23 19:45:01 +01:00
Родитель 7be8f72644
Коммит 011b4f01f4
4 изменённых файлов: 93 добавлений и 17 удалений

Просмотреть файл

@ -49,7 +49,7 @@ type DockerRegistrySuite struct {
func (s *DockerRegistrySuite) SetUpTest(c *check.C) { func (s *DockerRegistrySuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux) testRequires(c, DaemonIsLinux)
s.reg = setupRegistry(c, false) s.reg = setupRegistry(c, false, false)
s.d = NewDaemon(c) s.d = NewDaemon(c)
} }
@ -77,7 +77,7 @@ type DockerSchema1RegistrySuite struct {
func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) { func (s *DockerSchema1RegistrySuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux) testRequires(c, DaemonIsLinux)
s.reg = setupRegistry(c, true) s.reg = setupRegistry(c, true, false)
s.d = NewDaemon(c) s.d = NewDaemon(c)
} }
@ -91,6 +91,36 @@ func (s *DockerSchema1RegistrySuite) TearDownTest(c *check.C) {
s.ds.TearDownTest(c) s.ds.TearDownTest(c)
} }
func init() {
check.Suite(&DockerRegistryAuthSuite{
ds: &DockerSuite{},
})
}
type DockerRegistryAuthSuite struct {
ds *DockerSuite
reg *testRegistryV2
d *Daemon
}
func (s *DockerRegistryAuthSuite) SetUpTest(c *check.C) {
testRequires(c, DaemonIsLinux)
s.reg = setupRegistry(c, false, true)
s.d = NewDaemon(c)
}
func (s *DockerRegistryAuthSuite) TearDownTest(c *check.C) {
if s.reg != nil {
out, err := s.d.Cmd("logout", privateRegistryURL)
c.Assert(err, check.IsNil, check.Commentf(out))
s.reg.Close()
}
if s.d != nil {
s.d.Stop()
}
s.ds.TearDownTest(c)
}
func init() { func init() {
check.Suite(&DockerDaemonSuite{ check.Suite(&DockerDaemonSuite{
ds: &DockerSuite{}, ds: &DockerSuite{},
@ -128,7 +158,7 @@ type DockerTrustSuite struct {
} }
func (s *DockerTrustSuite) SetUpTest(c *check.C) { func (s *DockerTrustSuite) SetUpTest(c *check.C) {
s.reg = setupRegistry(c, false) s.reg = setupRegistry(c, false, false)
s.not = setupNotary(c) s.not = setupNotary(c)
} }

Просмотреть файл

@ -17,5 +17,14 @@ func (s *DockerSuite) TestLoginWithoutTTY(c *check.C) {
// run the command and block until it's done // run the command and block until it's done
err := cmd.Run() err := cmd.Run()
c.Assert(err, checker.NotNil) //"Expected non nil err when loginning in & TTY not available" c.Assert(err, checker.NotNil) //"Expected non nil err when loginning in & TTY not available"
}
func (s *DockerRegistryAuthSuite) TestLoginToPrivateRegistry(c *check.C) {
// wrong credentials
out, _, err := dockerCmdWithError("login", "-u", s.reg.username, "-p", "WRONGPASSWORD", "-e", s.reg.email, privateRegistryURL)
c.Assert(err, checker.NotNil, check.Commentf(out))
c.Assert(out, checker.Contains, "401 Unauthorized")
// now it's fine
dockerCmd(c, "login", "-u", s.reg.username, "-p", s.reg.password, "-e", s.reg.email, privateRegistryURL)
} }

Просмотреть файл

@ -1554,9 +1554,9 @@ func daemonTime(c *check.C) time.Time {
return dt return dt
} }
func setupRegistry(c *check.C, schema1 bool) *testRegistryV2 { func setupRegistry(c *check.C, schema1, auth bool) *testRegistryV2 {
testRequires(c, RegistryHosting) testRequires(c, RegistryHosting)
reg, err := newTestRegistryV2(c, schema1) reg, err := newTestRegistryV2(c, schema1, auth)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
// Wait for registry to be ready to serve requests. // Wait for registry to be ready to serve requests.

Просмотреть файл

@ -18,28 +18,55 @@ const (
) )
type testRegistryV2 struct { type testRegistryV2 struct {
cmd *exec.Cmd cmd *exec.Cmd
dir string dir string
username string
password string
email string
} }
func newTestRegistryV2(c *check.C, schema1 bool) (*testRegistryV2, error) { func newTestRegistryV2(c *check.C, schema1, auth bool) (*testRegistryV2, error) {
tmp, err := ioutil.TempDir("", "registry-test-")
if err != nil {
return nil, err
}
template := `version: 0.1 template := `version: 0.1
loglevel: debug loglevel: debug
storage: storage:
filesystem: filesystem:
rootdirectory: %s rootdirectory: %s
http: http:
addr: %s` addr: %s
tmp, err := ioutil.TempDir("", "registry-test-") %s`
if err != nil { var (
return nil, err htpasswd string
username string
password string
email string
)
if auth {
htpasswdPath := filepath.Join(tmp, "htpasswd")
// generated with: htpasswd -Bbn testuser testpassword
userpasswd := "testuser:$2y$05$sBsSqk0OpSD1uTZkHXc4FeJ0Z70wLQdAX/82UiHuQOKbNbBrzs63m"
username = "testuser"
password = "testpassword"
email = "test@test.org"
if err := ioutil.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0644)); err != nil {
return nil, err
}
htpasswd = fmt.Sprintf(`auth:
htpasswd:
realm: basic-realm
path: %s
`, htpasswdPath)
} }
confPath := filepath.Join(tmp, "config.yaml") confPath := filepath.Join(tmp, "config.yaml")
config, err := os.Create(confPath) config, err := os.Create(confPath)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL); err != nil { if _, err := fmt.Fprintf(config, template, tmp, privateRegistryURL, htpasswd); err != nil {
os.RemoveAll(tmp) os.RemoveAll(tmp)
return nil, err return nil, err
} }
@ -57,8 +84,11 @@ http:
return nil, err return nil, err
} }
return &testRegistryV2{ return &testRegistryV2{
cmd: cmd, cmd: cmd,
dir: tmp, dir: tmp,
username: username,
password: password,
email: email,
}, nil }, nil
} }
@ -68,7 +98,14 @@ func (t *testRegistryV2) Ping() error {
if err != nil { if err != nil {
return err return err
} }
if resp.StatusCode != http.StatusOK { resp.Body.Close()
fail := resp.StatusCode != http.StatusOK
if t.username != "" {
// unauthorized is a _good_ status when pinging v2/ and it needs auth
fail = fail && resp.StatusCode != http.StatusUnauthorized
}
if fail {
return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode) return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
} }
return nil return nil