Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add unit test for kubernetes object remediations #5636

Merged
merged 1 commit into from
Apr 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
21 changes: 21 additions & 0 deletions tests/unit/kubernetes/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
PROFILE?=
CONTENT_IMAGE?=
export ROOT_DIR=$(shell git rev-parse --show-toplevel)
TEST_DIR=$(ROOT_DIR)/tests/unit/kubernetes
TEST_FLAGS?=-v

.PHONY: all
all: unit

.PHONY: unit
unit: ## Run the unit tests.
pushd $(TEST_DIR) && \
go test $(TEST_FLAGS) .

.PHONY: help
help: ## Show this help screen
@echo 'Usage: make <OPTIONS> ... <TARGETS>'
@echo ''
@echo 'Available targets are:'
@echo ''
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z0-9_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)
47 changes: 47 additions & 0 deletions tests/unit/kubernetes/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
module ocp4unit

go 1.13

require (
github.com/ajeddeloh/go-json v0.0.0-20200220154158-5ae607161559 // indirect
github.com/coreos/ignition v0.35.0 // indirect
github.com/google/gofuzz v1.1.0 // indirect
github.com/openshift/machine-config-operator v4.2.0-alpha.0.0.20190917115525-033375cbe820+incompatible
github.com/vincent-petithory/dataurl v0.0.0-20191104211930-d1553a71de50 // indirect
go4.org v0.0.0-20200104003542-c7e774b10ea0 // indirect
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 // indirect
gopkg.in/yaml.v2 v2.2.8 // indirect
k8s.io/api v0.17.2 // indirect
k8s.io/apimachinery v0.17.2
)

replace (
github.com/go-log/log => github.com/go-log/log v0.1.1-0.20181211034820-a514cf01a3eb
github.com/openshift/machine-config-operator => github.com/openshift/machine-config-operator v0.0.1-0.20200305103412-b9fa5093eb95
k8s.io/api => k8s.io/api v0.0.0-20191016110408-35e52d86657a
k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.0.0-20191016113550-5357c4baaf65
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20191004115801-a2eda9f80ab8
k8s.io/apiserver => k8s.io/apiserver v0.0.0-20191016112112-5190913f932d
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20191016114015-74ad18325ed5
k8s.io/client-go => k8s.io/client-go v0.0.0-20191016111102-bec269661e48
k8s.io/cloud-provider => k8s.io/cloud-provider v0.0.0-20191016115326-20453efc2458
k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.0.0-20191016115129-c07a134afb42
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894
k8s.io/component-base => k8s.io/component-base v0.0.0-20191016111319-039242c015a9
k8s.io/cri-api => k8s.io/cri-api v0.0.0-20190828162817-608eb1dad4ac
k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.0.0-20191016115521-756ffa5af0bd
k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.0.0-20191016112429-9587704a8ad4
k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.0.0-20191016114939-2b2b218dc1df
k8s.io/kube-proxy => k8s.io/kube-proxy v0.0.0-20191016114407-2e83b6f20229
k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.0.0-20191016114748-65049c67a58b
k8s.io/kubectl => k8s.io/kubectl v0.0.0-20191016120415-2ed914427d51
k8s.io/kubelet => k8s.io/kubelet v0.0.0-20191016114556-7841ed97f1b2
k8s.io/kubernetes => k8s.io/kubernetes v1.17.1
k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.0.0-20191016115753-cf0698c3a16b
k8s.io/metrics => k8s.io/metrics v0.0.0-20191016113814-3b1a734dba6e
k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.0.0-20191016112829-06bb3c9d77c9
)

replace github.com/docker/docker => github.com/moby/moby v0.7.3-0.20190826074503-38ab9da00309 // Required by Helm

replace github.com/openshift/api => github.com/openshift/api v0.0.0-20190924102528-32369d4db2ad // Required until https://github.com/operator-framework/operator-lifecycle-manager/pull/1241 is resolved
999 changes: 999 additions & 0 deletions tests/unit/kubernetes/go.sum

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions tests/unit/kubernetes/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package ocp4unit

import (
"bufio"
"io"
"os"
"path/filepath"
"strings"
"testing"

mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
k8syaml "k8s.io/apimachinery/pkg/util/yaml"
)

type unitTestContext struct {
rootdir string
t *testing.T
}

func newUnitTestContext(t *testing.T) *unitTestContext {
rootdir := os.Getenv("ROOT_DIR")
if rootdir == "" {
rootdir = "../../../not valid"
}
return &unitTestContext{
rootdir: rootdir,
t: t,
}
}

func (ctx *unitTestContext) assertObjectIsValid(path string) *unstructured.Unstructured {
obj, err := readObjFromYAMLFilePath(path)

if err != nil {
ctx.t.Errorf("The object in the following path is malformed '%s': %s", path, err)
}

return obj
}

func (ctx *unitTestContext) assertMachineConfigIsValid(obj *unstructured.Unstructured, path string) {
mcfg := &mcfgv1.MachineConfig{}
unstructured := obj.UnstructuredContent()
err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstructured, mcfg)

if err != nil {
ctx.t.Errorf("The MachineConfig in the following path is not valid '%s': %s", path, err)
}
}

func (ctx *unitTestContext) assertWithRelevantFiles(assertion func(path string)) {
err := filepath.Walk(ctx.rootdir,
func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if isRelevantDir(path, info) {
filepath.Walk(path,
func(path string, info os.FileInfo, err error) error {
if isRelevantFile(path) {
assertion(path)
}
return nil
})
}
return nil
},
)
if err != nil {
ctx.t.Fatalf("Error wile walking through files %s", err)
}
}

func isMachineConfig(obj *unstructured.Unstructured) bool {
mcfg := &mcfgv1.MachineConfig{}
mcfggvk := mcfg.GroupVersionKind()
objgvk := obj.GroupVersionKind()
return mcfggvk.Kind == objgvk.Kind && mcfggvk.Group == objgvk.Group
}

func isRelevantDir(path string, info os.FileInfo) bool {
// We don't care about e2e tests
if strings.Contains(path, "ocp4e2e/") {
return false
}
// We don't care about this folder
if strings.Contains(path, "unit/kubernetes") {
return false
}
if strings.Contains(path, ".git/") {
return false
}
return info.IsDir() && (info.Name() == "ignition" || info.Name() == "kubernetes")
}

func isRelevantFile(path string) bool {
return strings.HasSuffix(path, ".yml")
}

// Reads a YAML file and returns an unstructured object from it. This object
// can be taken into use by the dynamic client
func readObjFromYAMLFilePath(path string) (*unstructured.Unstructured, error) {
nsyamlfile, err := os.Open(path)
if err != nil {
return nil, err
}
defer nsyamlfile.Close()

return readObjFromYAML(bufio.NewReader(nsyamlfile))
}

// Reads a YAML file and returns an unstructured object from it. This object
// can be taken into use by the dynamic client
func readObjFromYAML(r io.Reader) (*unstructured.Unstructured, error) {
obj := &unstructured.Unstructured{}
dec := k8syaml.NewYAMLToJSONDecoder(r)
err := dec.Decode(obj)
return obj, err
}
18 changes: 18 additions & 0 deletions tests/unit/kubernetes/unit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package ocp4unit

import (
"testing"
)

func TestUnit(t *testing.T) {
ctx := newUnitTestContext(t)
t.Run("Verify kubernetes files are correct", func(t *testing.T) {
ctx.assertWithRelevantFiles(func(path string) {
obj := ctx.assertObjectIsValid(path)

if isMachineConfig(obj) {
ctx.assertMachineConfigIsValid(obj, path)
}
})
})
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading