Files
skopeo/integration/registry_test.go
Miloslav Trmač 6a0b6b1c86 Update CI image and tests
registry-v2-schema1 is now registry-v2-schema1-only,
and there is a new registry-v2-schema1-supported because the default
/usr/bin/registry does not support schema1 any more.

Adjust tests.

Signed-off-by: Miloslav Trmač <mitr@redhat.com>
2026-03-10 19:02:36 +01:00

147 lines
3.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package main
import (
"fmt"
"net/http"
"os"
"os/exec"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
)
const (
binaryV2 = "registry"
binaryV2Schema1Only = "registry-v2-schema1-only"
binaryV2Schema1Supported = "registry-v2-schema1-supported"
)
type registryVersion int
const (
registryVersionInvalid registryVersion = iota
registryVersionModern // Whatever comes from a packaged docker-distribution; as of 2026-03 supports schema2, not schema1.
registryVersionSchema1Only // Supports only schema1
registryVersionSchema1Supported // Supports both schema1 and schema2
)
type testRegistryV2 struct {
cmd *exec.Cmd
url string
username string
password string
email string
}
func setupRegistryV2At(t *testing.T, url string, auth bool, version registryVersion) *testRegistryV2 {
reg, err := newTestRegistryV2At(t, url, auth, version)
require.NoError(t, err)
// Wait for registry to be ready to serve requests.
for range 50 {
if err = reg.Ping(); err == nil {
break
}
time.Sleep(100 * time.Millisecond)
}
if err != nil {
t.Fatal("Timeout waiting for test registry to become available")
}
return reg
}
func newTestRegistryV2At(t *testing.T, url string, auth bool, version registryVersion) (*testRegistryV2, error) {
tmp := t.TempDir()
template := `version: 0.1
loglevel: debug
storage:
filesystem:
rootdirectory: %s
delete:
enabled: true
http:
addr: %s
compatibility:
schema1:
enabled: true
%s`
var (
htpasswd string
username string
password string
email string
)
if auth {
htpasswdPath := filepath.Join(tmp, "htpasswd")
userpasswd := "testuser:$2y$05$sBsSqk0OpSD1uTZkHXc4FeJ0Z70wLQdAX/82UiHuQOKbNbBrzs63m"
username = "testuser"
password = "testpassword"
email = "test@test.org"
if err := os.WriteFile(htpasswdPath, []byte(userpasswd), os.FileMode(0o644)); err != nil {
return nil, err
}
htpasswd = fmt.Sprintf(`auth:
htpasswd:
realm: basic-realm
path: %s
`, htpasswdPath)
}
confPath := filepath.Join(tmp, "config.yaml")
config, err := os.Create(confPath)
if err != nil {
return nil, err
}
if _, err := fmt.Fprintf(config, template, tmp, url, htpasswd); err != nil {
return nil, err
}
var cmd *exec.Cmd
switch version {
case registryVersionModern:
cmd = exec.Command(binaryV2, "serve", confPath)
case registryVersionSchema1Only:
cmd = exec.Command(binaryV2Schema1Only, confPath)
case registryVersionSchema1Supported:
cmd = exec.Command(binaryV2Schema1Supported, "serve", confPath)
default:
return nil, fmt.Errorf("invalid registry version: %v", version)
}
consumeAndLogOutputs(t, fmt.Sprintf("registry-%s", url), cmd)
if err := cmd.Start(); err != nil {
if os.IsNotExist(err) {
t.Skip(err.Error())
}
return nil, err
}
return &testRegistryV2{
cmd: cmd,
url: url,
username: username,
password: password,
email: email,
}, nil
}
func (r *testRegistryV2) Ping() error {
// We always ping through HTTP for our test registry.
resp, err := http.Get(fmt.Sprintf("http://%s/v2/", r.url))
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusUnauthorized {
return fmt.Errorf("registry ping replied with an unexpected status code %d", resp.StatusCode)
}
return nil
}
func (r *testRegistryV2) tearDown() {
// Its undocumented what Kill() returns if the process has terminated,
// so we couldnt check just for that. This is running in a container anyway…
_ = r.cmd.Process.Kill()
}