test

package
v0.0.0-...-479019f Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 6, 2024 License: Apache-2.0 Imports: 47 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// VersionHeaderKey is the standard version header name included in all
	// Registry v2 API responses.
	VersionHeaderKey = "Docker-Distribution-Api-Version"
	// VersionHeaderValue is the standard version header value included in all
	// Registry v2 API responses.
	VersionHeaderValue = "registry/2.0"
)
View Source
const UnitTestAnycastIssuerEd25519PrivateKey = `-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIMk7vAS28DlAzYWG9yktmmAnla+wvvTo/Ah6qmXG6E+S
-----END PRIVATE KEY-----`

UnitTestAnycastIssuerEd25519PrivateKey is an ed25519 private key that can be used as KEPPEL_ISSUER_KEY in unit tests. DO NOT USE IN PRODUCTION.

View Source
const UnitTestAnycastIssuerRSAPrivateKey = `` /* 3242-byte string literal not displayed */

UnitTestAnycastIssuerRSAPrivateKey is an RSA private key that can be used as KEPPEL_ANYCAST_ISSUER_KEY in unit tests. DO NOT USE IN PRODUCTION.

View Source
const UnitTestIssuerEd25519PrivateKey = `-----BEGIN PRIVATE KEY-----
MC4CAQAwBQYDK2VwBCIEIJF8IUp7t4h64Xm9WDPtThzRHiQY5guceFs4z8QDrMQ0
-----END PRIVATE KEY-----`

UnitTestIssuerEd25519PrivateKey is an ed25519 private key that can be used as KEPPEL_ISSUER_KEY in unit tests. DO NOT USE IN PRODUCTION.

View Source
const UnitTestIssuerRSAPrivateKey = `` /* 3246-byte string literal not displayed */

UnitTestIssuerRSAPrivateKey is an RSA private key that can be used as KEPPEL_ISSUER_KEY in unit tests. DO NOT USE IN PRODUCTION.

Variables

View Source
var (
	// CADFReasonOK is a helper to make cadf.Event literals shorter.
	CADFReasonOK = cadf.Reason{
		ReasonType: "HTTP",
		ReasonCode: "200",
	}
)

VersionHeader is the standard version header included in all Registry v2 API responses.

Functions

func AddHeadersForCorrectAuthChallenge

func AddHeadersForCorrectAuthChallenge(hdr map[string]string) map[string]string

AddHeadersForCorrectAuthChallenge adds X-Forwarded-... headers to a request to ensure that the correct auth challenge gets generated. It won't work without these headers since the httptest library sets "Host: example.com" on all simulated HTTP requests.

func DeterministicDummyDigest

func DeterministicDummyDigest(counter int) digest.Digest

func GetReplicationPassword

func GetReplicationPassword() string

GetReplicationPassword returns the password that the secondary registry can use to replicate from the primary registry.

func ToJSON

func ToJSON(x any) string

ToJSON is a more compact equivalent of json.Marshal() that panics on error instead of returning it, and which returns string instead of []byte.

func WithKeppelAPI

func WithKeppelAPI(params *setupParams)

WithKeppelAPI is a SetupOption that enables the Keppel API.

func WithPeerAPI

func WithPeerAPI(params *setupParams)

WithPeerAPI is a SetupOption that enables the peer API.

func WithPreviousIssuerKey

func WithPreviousIssuerKey(params *setupParams)

WithPreviousIssuerKey is a SetupOption that will add the "previous" set of test issuer keys.

func WithQuotas

func WithQuotas(params *setupParams)

WithQuotas is a SetupOption that sets up ample quota for all configured accounts.

func WithRoundTripper

func WithRoundTripper(action func(*RoundTripper))

WithRoundTripper sets up a RoundTripper instance as the default HTTP transport for the duration of the given action.

func WithTrivyDouble

func WithTrivyDouble(params *setupParams)

WithTrivyDouble is a SetupOption that sets up a TrivyDouble at trivy.example.org.

func WithoutCurrentIssuerKey

func WithoutCurrentIssuerKey(params *setupParams)

WithoutCurrentIssuerKey is a SetupOption that will not add the "current" set of test issuer keys. Tokens will be issued with the "previous" set of issuer keys instead, so WithPreviousIssuerKey must be given as well.

func WithoutRoundTripper

func WithoutRoundTripper(action func())

WithoutRoundTripper can be used during WithRoundTripper() to temporarily revert back to the

Types

type AccountRecordedByFederationDriver

type AccountRecordedByFederationDriver struct {
	Account    models.Account
	RecordedAt time.Time
}

AccountRecordedByFederationDriver appears in type FederationDriver.

type Auditor

type Auditor struct {
	// contains filtered or unexported fields
}

Auditor is a test recorder that satisfies the keppel.Auditor interface.

func (*Auditor) ExpectEvents

func (a *Auditor) ExpectEvents(t *testing.T, expectedEvents ...cadf.Event)

ExpectEvents checks that the recorded events are equivalent to the supplied expectation.

func (*Auditor) IgnoreEventsUntilNow

func (a *Auditor) IgnoreEventsUntilNow()

IgnoreEventsUntilNow clears the list of recorded events, so that the next ExpectEvents() will only cover events generated after this point.

func (*Auditor) Record

func (a *Auditor) Record(params audittools.EventParameters)

Record implements the keppel.Auditor interface.

type AuthDriver

type AuthDriver struct {
	// for AuthenticateUser
	ExpectedUserName   string
	ExpectedPassword   string
	GrantedPermissions string
}

AuthDriver (driver ID "unittest") is a keppel.AuthDriver for unit tests.

func (*AuthDriver) AuthenticateUser

func (d *AuthDriver) AuthenticateUser(ctx context.Context, userName, password string) (keppel.UserIdentity, *keppel.RegistryV2Error)

AuthenticateUser implements the keppel.AuthDriver interface.

func (*AuthDriver) AuthenticateUserFromRequest

func (d *AuthDriver) AuthenticateUserFromRequest(r *http.Request) (keppel.UserIdentity, *keppel.RegistryV2Error)

AuthenticateUserFromRequest implements the keppel.AuthDriver interface.

func (*AuthDriver) Init

func (d *AuthDriver) Init(rc *redis.Client) error

Init implements the keppel.AuthDriver interface.

func (*AuthDriver) PluginTypeID

func (d *AuthDriver) PluginTypeID() string

PluginTypeID implements the keppel.AuthDriver interface.

type Bytes

type Bytes struct {
	Contents  []byte
	Digest    digest.Digest
	MediaType string
}

Bytes groups a bytestring with its digest.

func GenerateExampleLayer

func GenerateExampleLayer(seed int64) Bytes

GenerateExampleLayer generates a blob of 1 MiB that can be used like an image layer when constructing image manifests for unit tests. The contents are generated deterministically from the given seed.

func GenerateExampleLayerSize

func GenerateExampleLayerSize(seed, sizeMiB int64) Bytes

GenerateExampleLayerSize generates a blob of a configurable size that can be used like an image layer when constructing image manifests for unit tests. The contents are generated deterministically from the given seed.

func NewBytes

func NewBytes(contents []byte) Bytes

NewBytes makes a new Bytes instance.

func NewBytesFromFile

func NewBytesFromFile(path string) (Bytes, error)

NewBytesFromFile creates a Bytes instance with the contents of the given file.

func (Bytes) MustUpload

func (b Bytes) MustUpload(t *testing.T, s Setup, repo models.Repository) models.Blob

MustUpload uploads the blob via the Registry V2 API.

`h` must serve the Registry V2 API. `token` must be a Bearer token capable of pushing into the specified repo.

type ErrorCode

type ErrorCode keppel.RegistryV2ErrorCode

ErrorCode wraps keppel.RegistryV2ErrorCode with an implementation of the assert.HTTPResponseBody interface.

func (ErrorCode) AssertResponseBody

func (e ErrorCode) AssertResponseBody(t *testing.T, requestInfo string, responseBody []byte) bool

AssertResponseBody implements the assert.HTTPResponseBody interface.

type ErrorCodeWithMessage

type ErrorCodeWithMessage struct {
	Code    keppel.RegistryV2ErrorCode
	Message string
}

ErrorCodeWithMessage extends ErrorCode with an expected detail message.

func (ErrorCodeWithMessage) AssertResponseBody

func (e ErrorCodeWithMessage) AssertResponseBody(t *testing.T, requestInfo string, responseBody []byte) bool

AssertResponseBody implements the assert.HTTPResponseBody interface.

type FederationDriver

type FederationDriver struct {
	APIPublicHostName              string
	ClaimFailsBecauseOfUserError   bool
	ClaimFailsBecauseOfServerError bool
	ForfeitFails                   bool
	NextSubleaseTokenSecretToIssue string
	ValidSubleaseTokenSecrets      map[string]string // maps accountName => subleaseTokenSecret
	RecordedAccounts               []AccountRecordedByFederationDriver
}

FederationDriver (driver ID "unittest") is a keppel.FederationDriver for unit tests.

func (*FederationDriver) ClaimAccountName

func (d *FederationDriver) ClaimAccountName(ctx context.Context, account models.Account, subleaseTokenSecret string) (keppel.ClaimResult, error)

ClaimAccountName implements the keppel.FederationDriver interface.

func (*FederationDriver) FindPrimaryAccount

func (d *FederationDriver) FindPrimaryAccount(ctx context.Context, accountName string) (string, error)

FindPrimaryAccount implements the keppel.FederationDriver interface.

func (*FederationDriver) ForfeitAccountName

func (d *FederationDriver) ForfeitAccountName(ctx context.Context, account models.Account) error

ForfeitAccountName implements the keppel.FederationDriver interface.

func (*FederationDriver) Init

Init implements the keppel.FederationDriver interface.

func (*FederationDriver) IssueSubleaseTokenSecret

func (d *FederationDriver) IssueSubleaseTokenSecret(ctx context.Context, account models.Account) (string, error)

IssueSubleaseTokenSecret implements the keppel.FederationDriver interface.

func (*FederationDriver) PluginTypeID

func (d *FederationDriver) PluginTypeID() string

PluginTypeID implements the keppel.FederationDriver interface.

func (*FederationDriver) RecordExistingAccount

func (d *FederationDriver) RecordExistingAccount(ctx context.Context, account models.Account, now time.Time) error

RecordExistingAccount implements the keppel.FederationDriver interface.

type Image

type Image struct {
	Layers   []Bytes
	Config   Bytes
	Manifest Bytes
}

Image contains all the pieces of a Docker image. The Layers and Config must be uploaded to the registry as blobs.

func GenerateImage

func GenerateImage(layers ...Bytes) Image

GenerateImage makes an Image from the given bytes in a deterministic manner.

func GenerateImageWithCustomConfig

func GenerateImageWithCustomConfig(change func(map[string]any), layers ...Bytes) Image

func (Image) DigestRef

func (i Image) DigestRef() models.ManifestReference

DigestRef returns the ManifestReference for this manifest's digest.

func (Image) ImageRef

func (i Image) ImageRef(s Setup, repo models.Repository) models.ImageReference

ImageRef returns the ImageReference for this images.

func (Image) MustUpload

func (i Image) MustUpload(t *testing.T, s Setup, repo models.Repository, tagName string) models.Manifest

MustUpload uploads the image via the Registry V2 API. This also uploads all referenced blobs that do not exist in the DB yet.

`tagName` may be empty if the image is to be uploaded without tagging.

func (Image) SizeBytes

func (i Image) SizeBytes() uint64

SizeBytes returns the value that we expect in the DB column `manifests.size_bytes` for this image.

type ImageList

type ImageList struct {
	Images   []Image
	Manifest Bytes
}

ImageList contains all the pieces of a multi-architecture Docker image. This type is used for testing the behavior of Keppel with manifests that reference other manifests.

func GenerateImageList

func GenerateImageList(images ...Image) ImageList

GenerateImageList makes an ImageList containing the given images in a deterministic manner.

func (ImageList) DigestRef

func (l ImageList) DigestRef() models.ManifestReference

DigestRef returns the ManifestReference for this manifest's digest.

func (ImageList) ImageRef

func (l ImageList) ImageRef(s Setup, repo models.Repository) models.ImageReference

ImageRef returns the ImageReference for this ImageList.

func (ImageList) MustUpload

func (l ImageList) MustUpload(t *testing.T, s Setup, repo models.Repository, tagName string) models.Manifest

MustUpload uploads the image list via the Registry V2 API. This also uploads all referenced images that do not exist in the DB yet.

`tagName` may be empty if the image is to be uploaded without tagging.

func (ImageList) SizeBytes

func (l ImageList) SizeBytes() uint64

SizeBytes returns the value that we expect in the DB column `manifests.size_bytes` for this image.

type InboundCacheDriver

type InboundCacheDriver struct {
	MaxAge  time.Duration
	Entries map[models.ImageReference]inboundCacheEntry
}

InboundCacheDriver (driver ID "unittest") is a keppel.InboundCacheDriver for unit tests. It remembers all manifests ever pushed into it in-memory (which is a really bad idea for an production driver because of the potentially unbounded memory footprint).

func (*InboundCacheDriver) Init

Init implements the keppel.InboundCacheDriver interface.

func (*InboundCacheDriver) LoadManifest

func (d *InboundCacheDriver) LoadManifest(location models.ImageReference, now time.Time) (contents []byte, mediaType string, err error)

LoadManifest implements the keppel.InboundCacheDriver interface.

func (*InboundCacheDriver) PluginTypeID

func (d *InboundCacheDriver) PluginTypeID() string

PluginTypeID implements the keppel.InboundCacheDriver interface.

func (*InboundCacheDriver) StoreManifest

func (d *InboundCacheDriver) StoreManifest(location models.ImageReference, contents []byte, mediaType string, now time.Time) error

StoreManifest implements the keppel.InboundCacheDriver interface.

type RoundTripper

type RoundTripper struct {
	Handlers map[string]http.Handler
}

RoundTripper is a http.RoundTripper that redirects some domains to http.Handler instances.

func (*RoundTripper) RoundTrip

func (t *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error)

RoundTrip implements the http.RoundTripper interface.

type Setup

type Setup struct {
	// fields that are always set
	Config       keppel.Configuration
	DB           *keppel.DB
	Clock        *mock.Clock
	SIDGenerator *StorageIDGenerator
	Auditor      *Auditor
	AD           *AuthDriver
	FD           *FederationDriver
	SD           *trivial.StorageDriver
	ICD          *InboundCacheDriver
	Handler      http.Handler
	Ctx          context.Context //nolint: containedctx  // only used in tests
	Registry     *prometheus.Registry
	// fields that are only set if the respective With... setup option is included
	TrivyDouble *TrivyDouble
	// fields that are filled by WithAccount and WithRepo (in order)
	Accounts []*models.Account
	Repos    []*models.Repository
	// contains filtered or unexported fields
}

Setup contains all the pieces that are needed for most tests.

func NewSetup

func NewSetup(t *testing.T, opts ...SetupOption) Setup

NewSetup prepares most or all pieces of Keppel for a test.

func (Setup) ExpectBlobsExistInStorage

func (s Setup) ExpectBlobsExistInStorage(t *testing.T, blobs ...models.Blob)

ExpectBlobsExistInStorage is a test assertion.

func (Setup) ExpectBlobsMissingInStorage

func (s Setup) ExpectBlobsMissingInStorage(t *testing.T, blobs ...models.Blob)

ExpectBlobsMissingInStorage is a test assertion.

func (Setup) ExpectManifestsExistInStorage

func (s Setup) ExpectManifestsExistInStorage(t *testing.T, repoName string, manifests ...models.Manifest)

ExpectManifestsExistInStorage is a test assertion.

func (Setup) ExpectManifestsMissingInStorage

func (s Setup) ExpectManifestsMissingInStorage(t *testing.T, manifests ...models.Manifest)

ExpectManifestsMissingInStorage is a test assertion.

func (Setup) GetAnycastToken

func (s Setup) GetAnycastToken(t *testing.T, scopes ...string) string

GetAnycastToken is like GetToken, but instead returns a token for the anycast endpoint.

func (Setup) GetDomainRemappedToken

func (s Setup) GetDomainRemappedToken(t *testing.T, accountName string, scopes ...string) string

GetDomainRemappedToken is like GetToken, but instead returns a token for a domain-remapped API.

func (Setup) GetToken

func (s Setup) GetToken(t *testing.T, scopes ...string) string

GetToken obtains a token for use with the Registry V2 API.

`scopes` is a list of token scopes, e.g. "repository:test1/foo:pull". The necessary permissions will be inferred from the given scopes, and a dummy UserIdentity object for the user called "correctusername" will be embedded in the token.

type SetupOption

type SetupOption func(*setupParams)

SetupOption is an option that can be given to NewSetup().

func IsSecondaryTo

func IsSecondaryTo(s *Setup) SetupOption

IsSecondaryTo is a SetupOption that configures registry-secondary.example.org instead of registry.example.org. If a non-nil Setup instance is given, that's the Setup for the corresponding primary instance, and both sides will be configured to peer with each other.

func WithAccount

func WithAccount(account models.Account) SetupOption

WithAccount is a SetupOption that adds the given keppel.Account to the DB during NewSetup().

func WithAnycast

func WithAnycast(withAnycast bool) SetupOption

WithAnycast is a SetupOption that fills the anycast fields in keppel.Configuration if true is given.

func WithRateLimitEngine

func WithRateLimitEngine(rle *keppel.RateLimitEngine) SetupOption

WithRateLimitEngine is a SetupOption to use a RateLimitEngine in enabled APIs.

func WithRepo

func WithRepo(repo models.Repository) SetupOption

WithRepo is a SetupOption that adds the given keppel.Repository to the DB during NewSetup().

type StorageIDGenerator

type StorageIDGenerator struct {
	// contains filtered or unexported fields
}

StorageIDGenerator provides realistic-looking, but deterministic storage IDs for unit tests.

func (*StorageIDGenerator) Next

func (g *StorageIDGenerator) Next() string

Next returns the next storage ID.

type TrivyDouble

type TrivyDouble struct {
	T              *testing.T
	ReportError    map[models.ImageReference]bool
	ReportFixtures map[models.ImageReference]string
}

TrivyDouble acts as a test double for a Trivy API.

func NewTrivyDouble

func NewTrivyDouble() *TrivyDouble

NewTrivyDouble creates a TrivyDouble.

func (*TrivyDouble) AddTo

func (t *TrivyDouble) AddTo(r *mux.Router)

AddTo implements the api.API interface.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL