get.porter.sh/porter@v1.3.0/tests/tester/test_registry.go (about)

     1  package tester
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	"github.com/uwu-tools/magex/shx"
    12  )
    13  
    14  // TestRegistryAlias is the environment variable that contains a pre-configured
    15  // hostname alias that can be used to access localhost. This environment variable
    16  // is only set in on the linux and macos CI agents so that we can test a variant
    17  // of communicating with a registry that is unsecured but is not obviously "localhost" or 127.0.0.1.
    18  const TestRegistryAlias = "PORTER_TEST_REGISTRY_ALIAS"
    19  
    20  // TestRegistryOptions controls how a test registry is run.
    21  type TestRegistryOptions struct {
    22  	// UseTLS indicates the registry should use http, secured with a self-signed certificate.
    23  	UseTLS bool
    24  
    25  	// UseAlias indicates that when the TestRegistryAlias environment variable is set,
    26  	// the registry address use the hostname alias, and not localhost.
    27  	UseAlias bool
    28  }
    29  
    30  // TestRegistry is a temporary registry that is stopped when the test completes.
    31  type TestRegistry struct {
    32  	t           *testing.T
    33  	containerID string
    34  
    35  	// port that the registry is running on
    36  	port string
    37  
    38  	// closed tracks if Close has been called so that we only try to close once.
    39  	closed bool
    40  
    41  	// hostname is the address or name used to reference the registry
    42  	hostname string
    43  }
    44  
    45  // String prints the registry URI.
    46  func (t *TestRegistry) String() string {
    47  	return fmt.Sprintf("%s:%s", t.hostname, t.port)
    48  }
    49  
    50  // Close stops the registry.
    51  func (t *TestRegistry) Close() {
    52  	// Only call close once
    53  	if t.closed {
    54  		return
    55  	}
    56  
    57  	err := shx.RunE("docker", "rm", "-vf", t.containerID)
    58  	t.closed = true
    59  	assert.NoError(t.t, err)
    60  }
    61  
    62  // StartTestRegistry runs an OCI registry in a container,
    63  // returning details about the registry.
    64  // The registry is cleaned up by default when the test completes.
    65  func (t Tester) StartTestRegistry(opts TestRegistryOptions) *TestRegistry {
    66  	cmd := shx.Command("docker", "run", "-d", "-P", "--restart=always")
    67  
    68  	if opts.UseTLS {
    69  		certDir := filepath.Join(t.RepoRoot, "tests/integration/testdata/certs")
    70  		cmd.Args(
    71  			"-v", fmt.Sprintf("%s:/certs", certDir),
    72  			"-e", "REGISTRY_HTTP_TLS_CERTIFICATE=/certs/registry_auth.crt",
    73  			"-e", "REGISTRY_HTTP_TLS_KEY=/certs/registry_auth.key",
    74  		)
    75  	}
    76  
    77  	// The docker image name must go last
    78  	cmd.Args("registry:2")
    79  
    80  	var err error
    81  	reg := &TestRegistry{t: t.T}
    82  	reg.containerID, err = cmd.OutputE()
    83  	require.NoError(t.T, err, "Could not start a temporary registry")
    84  
    85  	// Automatically close the registry when the test is done
    86  	t.T.Cleanup(reg.Close)
    87  
    88  	// Get the port that it is running on
    89  	reg.port, err = shx.OutputE("docker", "inspect", reg.containerID, "--format", `{{ (index (index .NetworkSettings.Ports "5000/tcp") 0).HostPort }}`)
    90  	require.NoError(t.T, err, "Could not get the published port of the temporary registry")
    91  
    92  	// Determine if we have a hostname alias set up for the registry
    93  	var hostname string
    94  	if opts.UseAlias {
    95  		hostname = os.Getenv(TestRegistryAlias)
    96  	}
    97  	if hostname == "" {
    98  		hostname = "localhost"
    99  	}
   100  	reg.hostname = hostname
   101  
   102  	return reg
   103  }