Use bundle mock for container executor tests

Also:
 - Remove unnecessary bundle from baremetal executor
   tests.
 - Use inline output for container api tests and remove
   unnecessary test bundle files.
 - Fixed merge conflict.

Change-Id: I400fb18fb1595c34598b451be5ad3f12012bae63
Relates-To: #464
Relates-To: #465
This commit is contained in:
Vladimir Kozhukalov 2021-03-31 18:17:04 +03:00
parent 419300b277
commit a6b89c0c94
11 changed files with 118 additions and 100 deletions

View File

@ -30,17 +30,39 @@ import (
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
aircontainer "opendev.org/airship/airshipctl/pkg/container" aircontainer "opendev.org/airship/airshipctl/pkg/container"
"opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
"opendev.org/airship/airshipctl/pkg/util" "opendev.org/airship/airshipctl/pkg/util"
) )
func bundlePathToInput(t *testing.T, bundlePath string) io.Reader { const (
singleSecretBundleOutput = `---
apiVersion: airshipit.org/v1alpha1
kind: ClusterMap
metadata:
labels:
airshipit.org/deploy-k8s: "false"
name: main-map
map:
testCluster: {}
...
---
apiVersion: v1
kind: Secret
metadata:
name: test-script
type: Opaque
stringData:
script.sh: |
#!/bin/sh
echo WORKS! $var >&2
...
`
)
func testInput(t *testing.T) io.Reader {
t.Helper() t.Helper()
bundle, err := document.NewBundleByPath(bundlePath)
require.NoError(t, err)
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
err = bundle.Write(buf) _, err := buf.Write([]byte(singleSecretBundleOutput))
require.NoError(t, err) require.NoError(t, err)
return buf return buf
} }
@ -266,7 +288,7 @@ func TestGenericContainer(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
input := bundlePathToInput(t, "testdata/single") input := testInput(t)
client := aircontainer.NewV1Alpha1(tt.outputPath, input, tt.output, tt.containerAPI, "", tt.execFunc) client := aircontainer.NewV1Alpha1(tt.outputPath, input, tt.output, tt.containerAPI, "", tt.execFunc)
err := client.Run() err := client.Run()

View File

@ -1,2 +0,0 @@
resources:
- secret.yaml

View File

@ -1,18 +0,0 @@
---
apiVersion: v1
kind: Secret
metadata:
name: test-script
stringData:
script.sh: |
#!/bin/sh
echo WORKS! $var >&2
type: Opaque
---
apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-node: "true"
name: master-0-bmc-secret
type: Opaque

View File

View File

@ -1,9 +0,0 @@
---
apiVersion: airshipit.org/v1alpha1
kind: ClusterMap
metadata:
labels:
airshipit.org/deploy-k8s: "false"
name: main-map
map:
testCluster: {}

View File

@ -1,3 +0,0 @@
resources:
- secret.yaml
- cluster-map.yaml

View File

@ -1,9 +0,0 @@
apiVersion: v1
kind: Secret
metadata:
name: test-script
type: Opaque
stringData:
script.sh: |
#!/bin/sh
echo WORKS! $var >&2

View File

@ -69,7 +69,6 @@ func TestNewBMHExecutor(t *testing.T) {
execDoc := executorDoc(t, fmt.Sprintf(bmhExecutorTemplate, "reboot", "/home/iso-url")) execDoc := executorDoc(t, fmt.Sprintf(bmhExecutorTemplate, "reboot", "/home/iso-url"))
executor, err := executors.NewBaremetalExecutor(ifc.ExecutorConfig{ executor, err := executors.NewBaremetalExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: testBundleFactory(),
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, executor) assert.NotNil(t, executor)
@ -82,7 +81,6 @@ func TestNewBMHExecutor(t *testing.T) {
} }
executor, actualErr := executors.NewBaremetalExecutor(ifc.ExecutorConfig{ executor, actualErr := executors.NewBaremetalExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: testBundleFactory(),
}) })
assert.Equal(t, exepectedErr, actualErr) assert.Equal(t, exepectedErr, actualErr)
assert.Nil(t, executor) assert.Nil(t, executor)

View File

@ -17,6 +17,9 @@ package executors_test
import ( import (
"testing" "testing"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/cluster/clustermap"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
@ -104,15 +107,18 @@ func executorBundle(t *testing.T, s string) document.Bundle {
return b return b
} }
// TODO replace this test bundle factory with one that uses bundle mock
func testBundleFactory() document.BundleFactoryFunc {
return func() (document.Bundle, error) {
return document.NewBundleByPath(singleExecutorBundlePath)
}
}
func wrapError(err error) events.Event { func wrapError(err error) events.Event {
return events.NewEvent().WithErrorEvent(events.ErrorEvent{ return events.NewEvent().WithErrorEvent(events.ErrorEvent{
Error: err, Error: err,
}) })
} }
func testClusterMap(t *testing.T) clustermap.ClusterMap {
doc, err := document.NewDocumentFromBytes([]byte(singleExecutorClusterMap))
require.NoError(t, err)
require.NotNil(t, doc)
apiObj := v1alpha1.DefaultClusterMap()
err = doc.ToAPIObject(apiObj, v1alpha1.Scheme)
require.NoError(t, err)
return clustermap.NewClusterMap(apiObj)
}

View File

@ -14,16 +14,17 @@ package executors_test
import ( import (
"bytes" "bytes"
goerrors "errors"
"fmt" "fmt"
"io" "io"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"opendev.org/airship/airshipctl/pkg/api/v1alpha1" "opendev.org/airship/airshipctl/pkg/api/v1alpha1"
"opendev.org/airship/airshipctl/pkg/cluster/clustermap"
"opendev.org/airship/airshipctl/pkg/container" "opendev.org/airship/airshipctl/pkg/container"
"opendev.org/airship/airshipctl/pkg/document" "opendev.org/airship/airshipctl/pkg/document"
"opendev.org/airship/airshipctl/pkg/events" "opendev.org/airship/airshipctl/pkg/events"
@ -31,6 +32,7 @@ import (
"opendev.org/airship/airshipctl/pkg/phase/errors" "opendev.org/airship/airshipctl/pkg/phase/errors"
"opendev.org/airship/airshipctl/pkg/phase/executors" "opendev.org/airship/airshipctl/pkg/phase/executors"
"opendev.org/airship/airshipctl/pkg/phase/ifc" "opendev.org/airship/airshipctl/pkg/phase/ifc"
testdoc "opendev.org/airship/airshipctl/testutil/document"
) )
const ( const (
@ -72,27 +74,71 @@ metadata:
map: map:
testCluster: {} testCluster: {}
` `
singleExecutorBundlePath = "../../container/testdata/single"
refConfig = `apiVersion: v1
kind: Secret
metadata:
name: test-script
stringData:
script.sh: |
#!/bin/sh
echo WORKS! $var >&2
type: Opaque
`
) )
func testClusterMap(t *testing.T) clustermap.ClusterMap { func testContainerBundleFactory() document.BundleFactoryFunc {
doc, err := document.NewDocumentFromBytes([]byte(singleExecutorClusterMap)) return func() (document.Bundle, error) {
bundle := &testdoc.MockBundle{}
return bundle, nil
}
}
func testContainerBundleFactoryNoDocumentEntryPoint() document.BundleFactoryFunc {
return func() (document.Bundle, error) {
return nil, errors.ErrDocumentEntrypointNotDefined{}
}
}
func testContainerBundle(t *testing.T, content string) document.Bundle {
bundle := &testdoc.MockBundle{}
writer := &bytes.Buffer{}
bundle.On("Write", writer).
Return(nil).
Run(func(args mock.Arguments) {
arg, ok := args.Get(0).(*bytes.Buffer)
if ok {
_, err := arg.Write([]byte(content))
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, doc) }
apiObj := v1alpha1.DefaultClusterMap() })
err = doc.ToAPIObject(apiObj, v1alpha1.Scheme) return bundle
}
func testContainerPhaseConfigBundleNoDocs() document.Bundle {
bundle := &testdoc.MockBundle{}
bundle.On("SelectOne", mock.Anything).
Return(nil, goerrors.New("found no documents"))
return bundle
}
func testContainerPhaseConfigBundleRefConfig(t *testing.T) document.Bundle {
refConfigDoc, err := document.NewDocumentFromBytes([]byte(refConfig))
require.NoError(t, err) require.NoError(t, err)
return clustermap.NewClusterMap(apiObj) bundle := &testdoc.MockBundle{}
bundle.On("SelectOne", mock.Anything).
Return(refConfigDoc, nil)
return bundle
} }
func TestNewContainerExecutor(t *testing.T) { func TestNewContainerExecutor(t *testing.T) {
execDoc, err := document.NewDocumentFromBytes([]byte(containerExecutorDoc)) execDoc, errDoc := document.NewDocumentFromBytes([]byte(containerExecutorDoc))
require.NoError(t, err) require.NoError(t, errDoc)
t.Run("success new container executor", func(t *testing.T) { t.Run("success new container executor", func(t *testing.T) {
e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{ e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: testBundleFactory(), BundleFactory: testContainerBundleFactory(),
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, e) assert.NotNil(t, e)
@ -101,9 +147,7 @@ func TestNewContainerExecutor(t *testing.T) {
t.Run("error bundle factory", func(t *testing.T) { t.Run("error bundle factory", func(t *testing.T) {
e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{ e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: func() (document.Bundle, error) { BundleFactory: testdoc.ErrorBundleFactory,
return nil, fmt.Errorf("bundle error")
},
}) })
assert.Error(t, err) assert.Error(t, err)
assert.Nil(t, e) assert.Nil(t, e)
@ -112,9 +156,7 @@ func TestNewContainerExecutor(t *testing.T) {
t.Run("bundle factory - empty documentEntryPoint", func(t *testing.T) { t.Run("bundle factory - empty documentEntryPoint", func(t *testing.T) {
e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{ e, err := executors.NewContainerExecutor(ifc.ExecutorConfig{
ExecutorDocument: execDoc, ExecutorDocument: execDoc,
BundleFactory: func() (document.Bundle, error) { BundleFactory: testContainerBundleFactoryNoDocumentEntryPoint(),
return nil, errors.ErrDocumentEntrypointNotDefined{}
},
}) })
assert.NoError(t, err) assert.NoError(t, err)
assert.NotNil(t, e) assert.NotNil(t, e)
@ -132,6 +174,7 @@ func TestGenericContainer(t *testing.T) {
executorConfig ifc.ExecutorConfig executorConfig ifc.ExecutorConfig
runOptions ifc.RunOptions runOptions ifc.RunOptions
clientFunc container.ClientV1Alpha1FactoryFunc clientFunc container.ClientV1Alpha1FactoryFunc
phaseConfigBundle document.Bundle
}{ }{
{ {
name: "error unknown container type", name: "error unknown container type",
@ -165,6 +208,7 @@ func TestGenericContainer(t *testing.T) {
}, },
runOptions: ifc.RunOptions{DryRun: true}, runOptions: ifc.RunOptions{DryRun: true},
expectedErr: "found no documents", expectedErr: "found no documents",
phaseConfigBundle: testContainerPhaseConfigBundleNoDocs(),
}, },
{ {
name: "success dry run", name: "success dry run",
@ -181,30 +225,19 @@ func TestGenericContainer(t *testing.T) {
}, },
}, },
runOptions: ifc.RunOptions{DryRun: true}, runOptions: ifc.RunOptions{DryRun: true},
resultConfig: `apiVersion: v1 resultConfig: refConfig,
kind: Secret phaseConfigBundle: testContainerPhaseConfigBundleRefConfig(t),
metadata:
name: test-script
stringData:
script.sh: |
#!/bin/sh
echo WORKS! $var >&2
type: Opaque
`,
}, },
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt tt := tt
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
b, err := document.NewBundleByPath(singleExecutorBundlePath) executorBundle := testContainerBundle(t, "")
require.NoError(t, err)
phaseConfigBundle, err := document.NewBundleByPath(singleExecutorBundlePath)
require.NoError(t, err)
container := executors.ContainerExecutor{ containerExecutor := executors.ContainerExecutor{
ResultsDir: tt.outputPath, ResultsDir: tt.outputPath,
ExecutorBundle: b, ExecutorBundle: executorBundle,
Container: tt.containerAPI, Container: tt.containerAPI,
ClientFunc: tt.clientFunc, ClientFunc: tt.clientFunc,
Options: ifc.ExecutorConfig{ Options: ifc.ExecutorConfig{
@ -215,12 +248,12 @@ type: Opaque
}, },
}, },
ClusterMap: testClusterMap(t), ClusterMap: testClusterMap(t),
PhaseConfigBundle: phaseConfigBundle, PhaseConfigBundle: tt.phaseConfigBundle,
}, },
} }
ch := make(chan events.Event) ch := make(chan events.Event)
go container.Run(ch, tt.runOptions) go containerExecutor.Run(ch, tt.runOptions)
actualEvt := make([]events.Event, 0) actualEvt := make([]events.Event, 0)
for evt := range ch { for evt := range ch {
@ -237,7 +270,7 @@ type: Opaque
assert.NoError(t, e.ErrorEvent.Error) assert.NoError(t, e.ErrorEvent.Error)
assert.Equal(t, e.Type, events.GenericContainerType) assert.Equal(t, e.Type, events.GenericContainerType)
assert.Equal(t, e.GenericContainerEvent.Operation, events.GenericContainerStop) assert.Equal(t, e.GenericContainerEvent.Operation, events.GenericContainerStop)
assert.Equal(t, tt.resultConfig, container.Container.Config) assert.Equal(t, tt.resultConfig, containerExecutor.Container.Config)
} }
}) })
} }