mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-08-09 07:22:40 -04:00
cli: move image package into cli
Signed-off-by: Paul Meyer <49727155+katexochen@users.noreply.github.com>
This commit is contained in:
parent
f19a90527b
commit
3c24e3fa01
6 changed files with 2 additions and 2 deletions
337
cli/internal/image/image_test.go
Normal file
337
cli/internal/image/image_test.go
Normal file
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
Copyright (c) Edgeless Systems GmbH
|
||||
|
||||
SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package image
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
|
||||
"github.com/edgelesssys/constellation/v2/internal/config"
|
||||
"github.com/edgelesssys/constellation/v2/internal/file"
|
||||
"github.com/edgelesssys/constellation/v2/internal/versionsapi"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/goleak"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
goleak.VerifyTestMain(m)
|
||||
}
|
||||
|
||||
func TestGetReference(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
info versionsapi.ImageInfo
|
||||
provider cloudprovider.Provider
|
||||
variant string
|
||||
wantReference string
|
||||
wantErr bool
|
||||
}{
|
||||
"reference exists aws": {
|
||||
info: versionsapi.ImageInfo{AWS: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.AWS,
|
||||
variant: "someVariant",
|
||||
wantReference: "someReference",
|
||||
},
|
||||
"reference exists azure": {
|
||||
info: versionsapi.ImageInfo{Azure: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.Azure,
|
||||
variant: "someVariant",
|
||||
wantReference: "someReference",
|
||||
},
|
||||
"reference exists gcp": {
|
||||
info: versionsapi.ImageInfo{GCP: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.GCP,
|
||||
variant: "someVariant",
|
||||
wantReference: "someReference",
|
||||
},
|
||||
"reference exists qemu": {
|
||||
info: versionsapi.ImageInfo{QEMU: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.QEMU,
|
||||
variant: "someVariant",
|
||||
wantReference: "someReference",
|
||||
},
|
||||
"csp does not exist": {
|
||||
info: versionsapi.ImageInfo{AWS: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.Unknown,
|
||||
variant: "someVariant",
|
||||
wantErr: true,
|
||||
},
|
||||
"variant does not exist": {
|
||||
info: versionsapi.ImageInfo{AWS: map[string]string{"someVariant": "someReference"}},
|
||||
provider: cloudprovider.AWS,
|
||||
variant: "nonExistingVariant",
|
||||
wantErr: true,
|
||||
},
|
||||
"info is empty": {
|
||||
info: versionsapi.ImageInfo{},
|
||||
provider: cloudprovider.AWS,
|
||||
variant: "someVariant",
|
||||
wantErr: true,
|
||||
},
|
||||
"csp is nil": {
|
||||
info: versionsapi.ImageInfo{AWS: nil},
|
||||
provider: cloudprovider.AWS,
|
||||
variant: "someVariant",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
reference, err := getReferenceFromImageInfo(tc.provider, tc.variant, tc.info)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.wantReference, reference)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestVariant(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
csp cloudprovider.Provider
|
||||
config *config.Config
|
||||
wantVariant string
|
||||
wantErr bool
|
||||
}{
|
||||
"AWS region": {
|
||||
csp: cloudprovider.AWS,
|
||||
config: &config.Config{Image: "someImage", Provider: config.ProviderConfig{
|
||||
AWS: &config.AWSConfig{Region: "someRegion"},
|
||||
}},
|
||||
wantVariant: "someRegion",
|
||||
},
|
||||
"Azure cvm": {
|
||||
csp: cloudprovider.Azure,
|
||||
config: &config.Config{
|
||||
Image: "someImage", Provider: config.ProviderConfig{
|
||||
Azure: &config.AzureConfig{ConfidentialVM: func() *bool { b := true; return &b }()},
|
||||
},
|
||||
},
|
||||
wantVariant: "cvm",
|
||||
},
|
||||
"Azure trustedlaunch": {
|
||||
csp: cloudprovider.Azure,
|
||||
config: &config.Config{
|
||||
Image: "someImage", Provider: config.ProviderConfig{
|
||||
Azure: &config.AzureConfig{ConfidentialVM: func() *bool { b := false; return &b }()},
|
||||
},
|
||||
},
|
||||
wantVariant: "trustedlaunch",
|
||||
},
|
||||
"GCP": {
|
||||
csp: cloudprovider.GCP,
|
||||
config: &config.Config{Image: "someImage", Provider: config.ProviderConfig{
|
||||
GCP: &config.GCPConfig{},
|
||||
}},
|
||||
wantVariant: "sev-es",
|
||||
},
|
||||
"QEMU": {
|
||||
csp: cloudprovider.QEMU,
|
||||
config: &config.Config{Image: "someImage", Provider: config.ProviderConfig{
|
||||
QEMU: &config.QEMUConfig{},
|
||||
}},
|
||||
wantVariant: "default",
|
||||
},
|
||||
"invalid": {
|
||||
csp: cloudprovider.Provider(9999),
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
vari, err := variant(tc.csp, tc.config)
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.wantVariant, vari)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchReference(t *testing.T) {
|
||||
img := "ref/abc/stream/nightly/v1.2.3"
|
||||
newImgInfo := func() versionsapi.ImageInfo {
|
||||
return versionsapi.ImageInfo{
|
||||
Ref: "abc",
|
||||
Stream: "nightly",
|
||||
Version: "v1.2.3",
|
||||
QEMU: map[string]string{"default": "someReference"},
|
||||
AWS: map[string]string{"foo": "bar"},
|
||||
Azure: map[string]string{"foo": "bar"},
|
||||
GCP: map[string]string{"foo": "bar"},
|
||||
}
|
||||
}
|
||||
imgInfoPath := imageInfoFilename(newImgInfo())
|
||||
|
||||
testCases := map[string]struct {
|
||||
config *config.Config
|
||||
imageInfoFetcher versionsAPIImageInfoFetcher
|
||||
localFile []byte
|
||||
wantReference string
|
||||
wantErr bool
|
||||
}{
|
||||
"reference fetched remotely": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
imageInfoFetcher: &stubVersionsAPIImageFetcher{
|
||||
fetchImageInfoInfo: newImgInfo(),
|
||||
},
|
||||
wantReference: "someReference",
|
||||
},
|
||||
"reference fetched remotely fails": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
imageInfoFetcher: &stubVersionsAPIImageFetcher{
|
||||
fetchImageInfoErr: errors.New("failed"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
"reference fetched locally": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
localFile: func() []byte {
|
||||
info := newImgInfo()
|
||||
info.QEMU["default"] = "localOverrideReference"
|
||||
file, err := json.Marshal(info)
|
||||
require.NoError(t, err)
|
||||
return file
|
||||
}(),
|
||||
wantReference: "localOverrideReference",
|
||||
},
|
||||
"local file first": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
imageInfoFetcher: &stubVersionsAPIImageFetcher{
|
||||
fetchImageInfoInfo: newImgInfo(),
|
||||
},
|
||||
localFile: func() []byte {
|
||||
info := newImgInfo()
|
||||
info.QEMU["default"] = "localOverrideReference"
|
||||
file, err := json.Marshal(info)
|
||||
require.NoError(t, err)
|
||||
return file
|
||||
}(),
|
||||
wantReference: "localOverrideReference",
|
||||
},
|
||||
"local file is invalid": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
localFile: []byte("invalid"),
|
||||
wantErr: true,
|
||||
},
|
||||
"local file has invalid image info": {
|
||||
config: &config.Config{
|
||||
Image: img,
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
localFile: func() []byte {
|
||||
info := newImgInfo()
|
||||
info.Ref = ""
|
||||
file, err := json.Marshal(info)
|
||||
require.NoError(t, err)
|
||||
return file
|
||||
}(),
|
||||
wantErr: true,
|
||||
},
|
||||
"image version does not exist": {
|
||||
config: &config.Config{
|
||||
Image: "nonExistingImageName",
|
||||
Provider: config.ProviderConfig{QEMU: &config.QEMUConfig{}},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
require := require.New(t)
|
||||
|
||||
fs := afero.NewMemMapFs()
|
||||
af := &afero.Afero{Fs: fs}
|
||||
if tc.localFile != nil {
|
||||
fh := file.NewHandler(af)
|
||||
require.NoError(fh.Write(imgInfoPath, tc.localFile))
|
||||
}
|
||||
|
||||
fetcher := &Fetcher{
|
||||
fetcher: tc.imageInfoFetcher,
|
||||
fs: af,
|
||||
}
|
||||
|
||||
reference, err := fetcher.FetchReference(context.Background(), tc.config)
|
||||
|
||||
if tc.wantErr {
|
||||
assert.Error(err)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
assert.Equal(tc.wantReference, reference)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type stubVersionsAPIImageFetcher struct {
|
||||
fetchImageInfoInfo versionsapi.ImageInfo
|
||||
fetchImageInfoErr error
|
||||
}
|
||||
|
||||
func (f *stubVersionsAPIImageFetcher) FetchImageInfo(ctx context.Context, imageInfo versionsapi.ImageInfo) (
|
||||
versionsapi.ImageInfo, error,
|
||||
) {
|
||||
return f.fetchImageInfoInfo, f.fetchImageInfoErr
|
||||
}
|
||||
|
||||
func must(t *testing.T, err error) {
|
||||
t.Helper()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// roundTripFunc .
|
||||
type roundTripFunc func(req *http.Request) *http.Response
|
||||
|
||||
// RoundTrip .
|
||||
func (f roundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
return f(req), nil
|
||||
}
|
||||
|
||||
// newTestClient returns *http.Client with Transport replaced to avoid making real calls.
|
||||
func newTestClient(fn roundTripFunc) *http.Client {
|
||||
return &http.Client{
|
||||
Transport: fn,
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue