constellation/cli/internal/cloudcmd/clusterupgrade_test.go
Moritz Sanft 95cf4bdf21
cli: perform upgrades in-place in Terraform workspace (#2317)
* perform upgrades in-place in terraform workspace

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* update buildfiles

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* add iam upgrade apply test

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* update buildfiles

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* fix linter

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* make config fetcher stubbable

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* change workspace restoring behaviour

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* allow overwriting existing Terraform files

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* allow overwrites of TF variables

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* fix iam upgrade apply

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* fix embed directive

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* make loader test less brittle

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* pass upgrade ID to user

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* naming nit

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* use upgradeDir

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

* tidy

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>

---------

Signed-off-by: Moritz Sanft <58110325+msanft@users.noreply.github.com>
2023-09-14 11:51:20 +02:00

204 lines
5.1 KiB
Go

/*
Copyright (c) Edgeless Systems GmbH
SPDX-License-Identifier: AGPL-3.0-only
*/
package cloudcmd
import (
"context"
"io"
"path/filepath"
"testing"
"github.com/edgelesssys/constellation/v2/cli/internal/terraform"
"github.com/edgelesssys/constellation/v2/internal/cloud/cloudprovider"
"github.com/edgelesssys/constellation/v2/internal/constants"
"github.com/edgelesssys/constellation/v2/internal/file"
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPlanClusterUpgrade(t *testing.T) {
setUpFilesystem := func(existingFiles []string) file.Handler {
fs := afero.NewMemMapFs()
for _, f := range existingFiles {
require.NoError(t, afero.WriteFile(fs, f, []byte{}, 0o644))
}
return file.NewHandler(fs)
}
testCases := map[string]struct {
upgradeID string
tf *tfClusterUpgradeStub
fs file.Handler
want bool
wantErr bool
}{
"success no diff": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{},
fs: setUpFilesystem([]string{}),
},
"success diff": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{
planDiff: true,
},
fs: setUpFilesystem([]string{}),
want: true,
},
"prepare workspace error": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{
prepareWorkspaceErr: assert.AnError,
},
fs: setUpFilesystem([]string{}),
wantErr: true,
},
"plan error": {
tf: &tfClusterUpgradeStub{
planErr: assert.AnError,
},
fs: setUpFilesystem([]string{}),
wantErr: true,
},
"show plan error no diff": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{
showErr: assert.AnError,
},
fs: setUpFilesystem([]string{}),
},
"show plan error diff": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{
showErr: assert.AnError,
planDiff: true,
},
fs: setUpFilesystem([]string{}),
wantErr: true,
},
"workspace not clean": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{},
fs: setUpFilesystem([]string{filepath.Join(constants.UpgradeDir, "1234", constants.TerraformUpgradeBackupDir)}),
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
require := require.New(t)
u := &ClusterUpgrader{
tf: tc.tf,
policyPatcher: stubPolicyPatcher{},
fileHandler: tc.fs,
upgradeWorkspace: filepath.Join(constants.UpgradeDir, tc.upgradeID),
existingWorkspace: "test",
logLevel: terraform.LogLevelDebug,
}
diff, err := u.PlanClusterUpgrade(context.Background(), io.Discard, &terraform.QEMUVariables{}, cloudprovider.Unknown)
if tc.wantErr {
require.Error(err)
} else {
require.NoError(err)
require.Equal(tc.want, diff)
}
})
}
}
func TestApplyClusterUpgrade(t *testing.T) {
setUpFilesystem := func(upgradeID string, existingFiles ...string) file.Handler {
fh := file.NewHandler(afero.NewMemMapFs())
require.NoError(t,
fh.Write(
filepath.Join(constants.UpgradeDir, upgradeID, constants.TerraformUpgradeWorkingDir, "someFile"),
[]byte("some content"),
))
for _, f := range existingFiles {
require.NoError(t, fh.Write(f, []byte("some content")))
}
return fh
}
testCases := map[string]struct {
upgradeID string
tf *tfClusterUpgradeStub
policyPatcher stubPolicyPatcher
fs file.Handler
wantErr bool
}{
"success": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{},
fs: setUpFilesystem("1234"),
policyPatcher: stubPolicyPatcher{},
},
"apply error": {
upgradeID: "1234",
tf: &tfClusterUpgradeStub{
applyErr: assert.AnError,
},
fs: setUpFilesystem("1234"),
policyPatcher: stubPolicyPatcher{},
wantErr: true,
},
}
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
assert := require.New(t)
tc.tf.file = tc.fs
u := &ClusterUpgrader{
tf: tc.tf,
policyPatcher: stubPolicyPatcher{},
fileHandler: tc.fs,
upgradeWorkspace: filepath.Join(constants.UpgradeDir, tc.upgradeID),
existingWorkspace: "test",
logLevel: terraform.LogLevelDebug,
}
_, err := u.ApplyClusterUpgrade(context.Background(), cloudprovider.Unknown)
if tc.wantErr {
assert.Error(err)
} else {
assert.NoError(err)
}
})
}
}
type tfClusterUpgradeStub struct {
file file.Handler
applyErr error
planErr error
planDiff bool
showErr error
prepareWorkspaceErr error
}
func (t *tfClusterUpgradeStub) Plan(_ context.Context, _ terraform.LogLevel) (bool, error) {
return t.planDiff, t.planErr
}
func (t *tfClusterUpgradeStub) ShowPlan(_ context.Context, _ terraform.LogLevel, _ io.Writer) error {
return t.showErr
}
func (t *tfClusterUpgradeStub) ApplyCluster(_ context.Context, _ cloudprovider.Provider, _ terraform.LogLevel) (terraform.ApplyOutput, error) {
return terraform.ApplyOutput{}, t.applyErr
}
func (t *tfClusterUpgradeStub) PrepareUpgradeWorkspace(_, _ string, _ terraform.Variables) error {
return t.prepareWorkspaceErr
}