airshipctl/pkg/bootstrap/cloudinit/cloud-init_testutils.go

232 lines
5.7 KiB
Go

/*
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cloudinit
import (
"strings"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"opendev.org/airship/airshipctl/pkg/document"
testdoc "opendev.org/airship/airshipctl/testutil/document"
)
type testData struct {
docsCfg []string
secret string
ephUser string
ephNode string
bmh string
selectorNamespace string
selectorName string
mockErr1 interface{}
mockErr2 interface{}
mockErr3 interface{}
}
const (
ephNode = "airshipit.org/ephemeral-node in (True, true)"
secret = "Secret"
bmh = "BareMetalHost"
ephUser = "airshipit.org/ephemeral-user-data in (True, true)"
ephUserData = `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: 'true'
name: networkdatamalformed-malformed
type: Opaque
stringData:
userData: cloud-init
`
ephUserDataMalformed = `apiVersion: v1
kind: Secret
metadata:
labels:
airshipit.org/ephemeral-user-data: 'true'
test: userdatamalformed
name: userdatamalformed-somesecret
type: Opaque
stringData:
no-user-data: this secret has the right label but is missing the 'user-data' key
`
ephUserDataNoLabel = `apiVersion: v1
kind: Secret
metadata:
labels:
test: userdatamissing
name: userdatamissing-somesecret
type: Opaque
stringData:
userData: "this secret lacks the label airshipit.org/ephemeral-user-data: true"`
ephUserDataCredentials = `apiVersion: v1
kind: Secret
metadata:
labels:
name: master-1-bmc
type: Opaque
stringData:
username: foobar
password: goober
`
bmhMaster1 = `apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
labels:
airshipit.org/ephemeral-node: 'true'
name: master-1
spec:
bmc:
address: ipmi://127.0.0.1
credentialsName: master-1-bmc
networkData:
name: master-1-networkdata
namespace: metal3
`
netDataMalFormed = `apiVersion: v1
kind: Secret
metadata:
labels:
name: networkdatamalformed-malformed
namespace: malformed
type: Opaque
stringData:
no-net-data-key: the required 'net-data' key is missing
`
bmhDuplicate = `apiVersion: metal3.io/v1alpha1
kind: BareMetalHost
metadata:
labels:
test: ephemeralduplicate
airshipit.org/ephemeral-node: 'true'
name: ephemeralduplicate-master-1
`
ephMissing = `apiVersion: v1
kind: Secret
metadata:
labels:
test: ephemeralmissing
name: ephemeralmissing
type: Opaque
`
ephNetValid = `apiVersion: v1
kind: Secret
metadata:
labels:
test: validdocset
name: master-1-networkdata
namespace: metal3
type: Opaque
stringData:
networkData: net-config
`
)
func getValidDocSet() []string {
return []string{
ephUserData,
bmhMaster1,
ephNetValid,
ephUserDataCredentials,
}
}
func getEphemeralMissing() []string {
return []string{
ephUserData,
ephMissing,
bmhMaster1,
}
}
func getEphemeralDuplicate() []string {
return []string{
ephUserData,
bmhDuplicate,
bmhDuplicate,
}
}
func getNetworkBadPointer() []string {
return []string{
ephUserData,
bmhMaster1,
ephUserDataCredentials,
}
}
func getNetDataMalformed() []string {
return []string{
ephUserData,
bmhMaster1,
netDataMalFormed,
ephUserDataCredentials,
}
}
func getUserDataMalformed() []string {
return []string{
ephUserDataMalformed,
}
}
func getUserDataMissing() []string {
return []string{
ephUserDataNoLabel,
}
}
func createTestBundle(t *testing.T, td testData) document.Bundle {
bundle := &testdoc.MockBundle{}
allDocs := make([]document.Document, len(td.docsCfg))
returnedDocs := make(map[string]document.Document)
for i, cfg := range td.docsCfg {
doc, err := document.NewDocumentFromBytes([]byte(cfg))
require.NoError(t, err)
allDocs[i] = doc
kind, selectorMap, name, namespace := doc.GetKind(), doc.GetLabels(), doc.GetName(), doc.GetNamespace()
// We use data in the document to determine which document should be returned from each mock
// function call.
if _, ok := selectorMap[strings.TrimSuffix(td.ephUser, " in (True, true)")]; ok && kind == td.secret {
returnedDocs["userDataDoc"] = doc
// initialize these two key-value pairs so that we avoid
// memory address errors. These will be overwritten.
returnedDocs["bmhDoc"] = doc
returnedDocs["ephOrBmhDoc"] = doc
} else if _, ok := selectorMap[strings.TrimSuffix(td.ephNode, " in (True, true)")]; ok && kind == td.bmh {
returnedDocs["bmhDoc"] = doc
} else if kind == td.secret && name == td.selectorName && namespace == td.selectorNamespace {
returnedDocs["ephOrBmhDoc"] = doc
}
}
bundle.On("GetAllDocuments").Return(allDocs, nil)
bundle.On("SelectOne", mock.MatchedBy(func(selector document.Selector) bool {
return selector.Kind == td.secret && selector.LabelSelector == td.ephUser
})).
Return(returnedDocs["userDataDoc"], td.mockErr1)
bundle.On("SelectOne", mock.MatchedBy(func(selector document.Selector) bool {
return selector.Kind == td.bmh && selector.LabelSelector == td.ephNode
})).
Return(returnedDocs["bmhDoc"], td.mockErr2)
bundle.On("SelectOne", mock.MatchedBy(func(selector document.Selector) bool {
return selector.Kind == td.secret && selector.Namespace == td.selectorNamespace && selector.Name == td.selectorName
})).
Return(returnedDocs["ephOrBmhDoc"], td.mockErr3)
return bundle
}