mirror of
https://github.com/aquasecurity/kube-bench.git
synced 2024-11-25 09:28:16 +00:00
c3e3c4c31c
Signed-off-by: guoguangwu <guoguangwu@magic-shield.com> Co-authored-by: chenk <hen.keinan@gmail.com>
769 lines
22 KiB
Go
769 lines
22 KiB
Go
// Copyright © 2017 Aqua Security Software Ltd. <info@aquasec.com>
|
|
//
|
|
// 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
|
|
//
|
|
// http://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 cmd
|
|
|
|
import (
|
|
"errors"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"sort"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/magiconair/properties/assert"
|
|
|
|
"github.com/aquasecurity/kube-bench/check"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
var (
|
|
g string
|
|
e []error
|
|
eIndex int
|
|
)
|
|
|
|
func fakeps(proc string) string {
|
|
return g
|
|
}
|
|
|
|
func fakestat(file string) (os.FileInfo, error) {
|
|
err := e[eIndex]
|
|
eIndex++
|
|
return nil, err
|
|
}
|
|
|
|
func TestVerifyBin(t *testing.T) {
|
|
cases := []struct {
|
|
proc string
|
|
psOut string
|
|
exp bool
|
|
}{
|
|
{proc: "single", psOut: "single", exp: true},
|
|
{proc: "single", psOut: "", exp: false},
|
|
{proc: "two words", psOut: "two words", exp: true},
|
|
{proc: "two words", psOut: "", exp: false},
|
|
{proc: "cmd", psOut: "cmd param1 param2", exp: true},
|
|
{proc: "cmd param", psOut: "cmd param1 param2", exp: true},
|
|
{proc: "cmd param", psOut: "cmd", exp: false},
|
|
{proc: "cmd", psOut: "cmd x \ncmd y", exp: true},
|
|
{proc: "cmd y", psOut: "cmd x \ncmd y", exp: true},
|
|
{proc: "cmd", psOut: "/usr/bin/cmd", exp: true},
|
|
{proc: "cmd", psOut: "kube-cmd", exp: false},
|
|
{proc: "cmd", psOut: "/usr/bin/kube-cmd", exp: false},
|
|
}
|
|
|
|
psFunc = fakeps
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
g = c.psOut
|
|
v := verifyBin(c.proc)
|
|
if v != c.exp {
|
|
t.Fatalf("Expected %v got %v", c.exp, v)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestFindExecutable(t *testing.T) {
|
|
cases := []struct {
|
|
candidates []string // list of executables we'd consider
|
|
psOut string // fake output from ps
|
|
exp string // the one we expect to find in the (fake) ps output
|
|
expErr bool
|
|
}{
|
|
{candidates: []string{"one", "two", "three"}, psOut: "two", exp: "two"},
|
|
{candidates: []string{"one", "two", "three"}, psOut: "two three", exp: "two"},
|
|
{candidates: []string{"one double", "two double", "three double"}, psOut: "two double is running", exp: "two double"},
|
|
{candidates: []string{"one", "two", "three"}, psOut: "blah", expErr: true},
|
|
{candidates: []string{"one double", "two double", "three double"}, psOut: "two", expErr: true},
|
|
{candidates: []string{"apiserver", "kube-apiserver"}, psOut: "kube-apiserver", exp: "kube-apiserver"},
|
|
{candidates: []string{"apiserver", "kube-apiserver", "hyperkube-apiserver"}, psOut: "kube-apiserver", exp: "kube-apiserver"},
|
|
}
|
|
|
|
psFunc = fakeps
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
g = c.psOut
|
|
e, err := findExecutable(c.candidates)
|
|
if e != c.exp {
|
|
t.Fatalf("Expected %v got %v", c.exp, e)
|
|
}
|
|
|
|
if err == nil && c.expErr {
|
|
t.Fatalf("Expected error")
|
|
}
|
|
|
|
if err != nil && !c.expErr {
|
|
t.Fatalf("Didn't expect error: %v", err)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetBinaries(t *testing.T) {
|
|
cases := []struct {
|
|
config map[string]interface{}
|
|
psOut string
|
|
exp map[string]string
|
|
expectErr bool
|
|
}{
|
|
{
|
|
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}},
|
|
psOut: "kube-apiserver",
|
|
exp: map[string]string{"apiserver": "kube-apiserver"},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
// "thing" is not in the list of components
|
|
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
|
|
psOut: "kube-apiserver thing",
|
|
exp: map[string]string{"apiserver": "kube-apiserver"},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
// "anotherthing" in list of components but doesn't have a definition
|
|
config: map[string]interface{}{"components": []string{"apiserver", "anotherthing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
|
|
psOut: "kube-apiserver thing",
|
|
exp: map[string]string{"apiserver": "kube-apiserver"},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
// more than one component
|
|
config: map[string]interface{}{"components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}},
|
|
psOut: "kube-apiserver \nthing",
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
// default binary to component name
|
|
config: map[string]interface{}{"components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}, "optional": true}},
|
|
psOut: "kube-apiserver \notherthing some params",
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
|
|
expectErr: false,
|
|
},
|
|
{
|
|
// missing mandatory component
|
|
config: map[string]interface{}{"components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}, "optional": true}},
|
|
psOut: "otherthing some params",
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
|
|
expectErr: true,
|
|
},
|
|
}
|
|
|
|
v := viper.New()
|
|
psFunc = fakeps
|
|
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
g = c.psOut
|
|
for k, val := range c.config {
|
|
v.Set(k, val)
|
|
}
|
|
m, err := getBinaries(v, check.MASTER)
|
|
if c.expectErr {
|
|
if err == nil {
|
|
t.Fatal("Got nil Expected error")
|
|
}
|
|
} else if !reflect.DeepEqual(m, c.exp) {
|
|
t.Fatalf("Got %v\nExpected %v", m, c.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMultiWordReplace(t *testing.T) {
|
|
cases := []struct {
|
|
input string
|
|
sub string
|
|
subname string
|
|
output string
|
|
}{
|
|
{input: "Here's a file with no substitutions", sub: "blah", subname: "blah", output: "Here's a file with no substitutions"},
|
|
{input: "Here's a file with a substitution", sub: "blah", subname: "substitution", output: "Here's a file with a blah"},
|
|
{input: "Here's a file with multi-word substitutions", sub: "multi word", subname: "multi-word", output: "Here's a file with 'multi word' substitutions"},
|
|
{input: "Here's a file with several several substitutions several", sub: "blah", subname: "several", output: "Here's a file with blah blah substitutions blah"},
|
|
}
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
s := multiWordReplace(c.input, c.subname, c.sub)
|
|
if s != c.output {
|
|
t.Fatalf("Expected %s got %s", c.output, s)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getVersionFromKubectlOutput(t *testing.T) {
|
|
ver := getVersionFromKubectlOutput(`{
|
|
"serverVersion": {
|
|
"major": "1",
|
|
"minor": "8",
|
|
"gitVersion": "v1.8.0"
|
|
}
|
|
}`)
|
|
if ver.BaseVersion() != "1.8" {
|
|
t.Fatalf("Expected 1.8 got %s", ver.BaseVersion())
|
|
}
|
|
|
|
ver = getVersionFromKubectlOutput("Something completely different")
|
|
if ver.BaseVersion() != defaultKubeVersion {
|
|
t.Fatalf("Expected %s got %s", defaultKubeVersion, ver.BaseVersion())
|
|
}
|
|
}
|
|
|
|
func TestFindConfigFile(t *testing.T) {
|
|
cases := []struct {
|
|
input []string
|
|
statResults []error
|
|
exp string
|
|
}{
|
|
{input: []string{"myfile"}, statResults: []error{nil}, exp: "myfile"},
|
|
{input: []string{"thisfile", "thatfile"}, statResults: []error{os.ErrNotExist, nil}, exp: "thatfile"},
|
|
{input: []string{"thisfile", "thatfile"}, statResults: []error{os.ErrNotExist, os.ErrNotExist}, exp: ""},
|
|
{input: []string{"thisfile", "/etc/dummy/thatfile"}, statResults: []error{os.ErrNotExist, errors.New("stat /etc/dummy/thatfile: not a directory")}, exp: ""},
|
|
}
|
|
|
|
statFunc = fakestat
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
e = c.statResults
|
|
eIndex = 0
|
|
conf := findConfigFile(c.input)
|
|
if conf != c.exp {
|
|
t.Fatalf("Got %s expected %s", conf, c.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfigFiles(t *testing.T) {
|
|
cases := []struct {
|
|
config map[string]interface{}
|
|
exp map[string]string
|
|
statResults []error
|
|
}{
|
|
{
|
|
config: map[string]interface{}{"components": []string{"apiserver"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}},
|
|
statResults: []error{os.ErrNotExist, nil},
|
|
exp: map[string]string{"apiserver": "kube-apiserver"},
|
|
},
|
|
{
|
|
// Component "thing" isn't included in the list of components
|
|
config: map[string]interface{}{
|
|
"components": []string{"apiserver"},
|
|
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
|
|
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil},
|
|
exp: map[string]string{"apiserver": "kube-apiserver"},
|
|
},
|
|
{
|
|
// More than one component
|
|
config: map[string]interface{}{
|
|
"components": []string{"apiserver", "thing"},
|
|
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
|
|
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, nil},
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "/my/file/thing"},
|
|
},
|
|
{
|
|
// Default thing to specified default config
|
|
config: map[string]interface{}{
|
|
"components": []string{"apiserver", "thing"},
|
|
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
|
|
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}, "defaultconf": "another/thing"},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "another/thing"},
|
|
},
|
|
{
|
|
// Default thing to component name
|
|
config: map[string]interface{}{
|
|
"components": []string{"apiserver", "thing"},
|
|
"apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}},
|
|
"thing": map[string]interface{}{"confs": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
|
|
exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"},
|
|
},
|
|
}
|
|
|
|
v := viper.New()
|
|
statFunc = fakestat
|
|
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
for k, val := range c.config {
|
|
v.Set(k, val)
|
|
}
|
|
e = c.statResults
|
|
eIndex = 0
|
|
|
|
m := getFiles(v, "config")
|
|
if !reflect.DeepEqual(m, c.exp) {
|
|
t.Fatalf("Got %v\nExpected %v", m, c.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetServiceFiles(t *testing.T) {
|
|
cases := []struct {
|
|
config map[string]interface{}
|
|
exp map[string]string
|
|
statResults []error
|
|
}{
|
|
{
|
|
config: map[string]interface{}{
|
|
"components": []string{"kubelet"},
|
|
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil},
|
|
exp: map[string]string{"kubelet": "10-kubeadm.conf"},
|
|
},
|
|
{
|
|
// Component "thing" isn't included in the list of components
|
|
config: map[string]interface{}{
|
|
"components": []string{"kubelet"},
|
|
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
|
|
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil},
|
|
exp: map[string]string{"kubelet": "10-kubeadm.conf"},
|
|
},
|
|
{
|
|
// More than one component
|
|
config: map[string]interface{}{
|
|
"components": []string{"kubelet", "thing"},
|
|
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
|
|
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, nil},
|
|
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "/my/file/thing"},
|
|
},
|
|
{
|
|
// Default thing to specified default service
|
|
config: map[string]interface{}{
|
|
"components": []string{"kubelet", "thing"},
|
|
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
|
|
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}, "defaultsvc": "another/thing"},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
|
|
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "another/thing"},
|
|
},
|
|
{
|
|
// Default thing to component name
|
|
config: map[string]interface{}{
|
|
"components": []string{"kubelet", "thing"},
|
|
"kubelet": map[string]interface{}{"svc": []string{"kubelet", "10-kubeadm.conf"}},
|
|
"thing": map[string]interface{}{"svc": []string{"/my/file/thing"}},
|
|
},
|
|
statResults: []error{os.ErrNotExist, nil, os.ErrNotExist},
|
|
exp: map[string]string{"kubelet": "10-kubeadm.conf", "thing": "thing"},
|
|
},
|
|
}
|
|
|
|
v := viper.New()
|
|
statFunc = fakestat
|
|
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
for k, val := range c.config {
|
|
v.Set(k, val)
|
|
}
|
|
e = c.statResults
|
|
eIndex = 0
|
|
|
|
m := getFiles(v, "service")
|
|
if !reflect.DeepEqual(m, c.exp) {
|
|
t.Fatalf("Got %v\nExpected %v", m, c.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetDatadirFiles(t *testing.T) {
|
|
var err error
|
|
datadir, err := os.MkdirTemp("", "kube-bench-test-etcd-data-dir")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp directory")
|
|
}
|
|
defer os.RemoveAll(datadir)
|
|
|
|
cases := []struct {
|
|
config map[string]interface{}
|
|
exp map[string]string
|
|
statResults []error
|
|
}{
|
|
{
|
|
config: map[string]interface{}{
|
|
"components": []string{"etcd"},
|
|
"etcd": map[string]interface{}{"datadirs": []string{datadir},
|
|
"defaultdatadir": "/var/lib/etcd/default.etcd"},
|
|
},
|
|
statResults: []error{nil},
|
|
exp: map[string]string{"etcd": datadir},
|
|
},
|
|
// fallback to defaultdatadir
|
|
{
|
|
config: map[string]interface{}{
|
|
"components": []string{"etcd"},
|
|
"etcd": map[string]interface{}{"datadirs": []string{"/path/to/etcd/data.etcd"},
|
|
"defaultdatadir": "/var/lib/etcd/default.etcd"},
|
|
},
|
|
statResults: []error{os.ErrNotExist},
|
|
exp: map[string]string{"etcd": "/var/lib/etcd/default.etcd"},
|
|
},
|
|
}
|
|
|
|
v := viper.New()
|
|
statFunc = fakestat
|
|
|
|
for id, c := range cases {
|
|
t.Run(strconv.Itoa(id), func(t *testing.T) {
|
|
for k, val := range c.config {
|
|
v.Set(k, val)
|
|
}
|
|
e = c.statResults
|
|
eIndex = 0
|
|
m := getFiles(v, "datadir")
|
|
if !reflect.DeepEqual(m, c.exp) {
|
|
t.Fatalf("Got %v\nExpected %v", m, c.exp)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestMakeSubsitutions(t *testing.T) {
|
|
cases := []struct {
|
|
input string
|
|
subst map[string]string
|
|
exp string
|
|
expectedSubs []string
|
|
}{
|
|
{input: "Replace $thisbin", subst: map[string]string{"this": "that"}, exp: "Replace that", expectedSubs: []string{"that"}},
|
|
{input: "Replace $thisbin", subst: map[string]string{"this": "that", "here": "there"}, exp: "Replace that", expectedSubs: []string{"that"}},
|
|
{input: "Replace $thisbin and $herebin", subst: map[string]string{"this": "that", "here": "there"}, exp: "Replace that and there", expectedSubs: []string{"that", "there"}},
|
|
}
|
|
for _, c := range cases {
|
|
t.Run(c.input, func(t *testing.T) {
|
|
s, subs := makeSubstitutions(c.input, "bin", c.subst)
|
|
if s != c.exp {
|
|
t.Fatalf("Got %s expected %s", s, c.exp)
|
|
}
|
|
sort.Strings(subs)
|
|
assert.Equal(t, c.expectedSubs, subs)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetConfigFilePath(t *testing.T) {
|
|
var err error
|
|
cfgDir, err = os.MkdirTemp("", "kube-bench-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp directory")
|
|
}
|
|
defer os.RemoveAll(cfgDir)
|
|
d := filepath.Join(cfgDir, "cis-1.4")
|
|
err = os.Mkdir(d, 0766)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir")
|
|
}
|
|
err = os.WriteFile(filepath.Join(d, "master.yaml"), []byte("hello world"), 0666)
|
|
if err != nil {
|
|
t.Logf("Failed to create temp file")
|
|
}
|
|
|
|
cases := []struct {
|
|
benchmarkVersion string
|
|
succeed bool
|
|
exp string
|
|
}{
|
|
{benchmarkVersion: "cis-1.4", succeed: true, exp: d},
|
|
{benchmarkVersion: "cis-1.5", succeed: false, exp: ""},
|
|
{benchmarkVersion: "1.1", succeed: false, exp: ""},
|
|
}
|
|
|
|
for _, c := range cases {
|
|
t.Run(c.benchmarkVersion, func(t *testing.T) {
|
|
path, err := getConfigFilePath(c.benchmarkVersion, "/master.yaml")
|
|
if c.succeed {
|
|
if err != nil {
|
|
t.Fatalf("Error %v", err)
|
|
}
|
|
if path != c.exp {
|
|
t.Fatalf("Got %s expected %s", path, c.exp)
|
|
}
|
|
} else {
|
|
if err == nil {
|
|
t.Fatalf("Expected Error, but none")
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDecrementVersion(t *testing.T) {
|
|
cases := []struct {
|
|
kubeVersion string
|
|
succeed bool
|
|
exp string
|
|
}{
|
|
{kubeVersion: "1.13", succeed: true, exp: "1.12"},
|
|
{kubeVersion: "1.15", succeed: true, exp: "1.14"},
|
|
{kubeVersion: "1.11", succeed: true, exp: "1.10"},
|
|
{kubeVersion: "1.1", succeed: true, exp: ""},
|
|
{kubeVersion: "invalid", succeed: false, exp: ""},
|
|
}
|
|
for _, c := range cases {
|
|
rv := decrementVersion(c.kubeVersion)
|
|
if c.succeed {
|
|
if c.exp != rv {
|
|
t.Fatalf("decrementVersion(%q) - Got %q expected %s", c.kubeVersion, rv, c.exp)
|
|
}
|
|
} else {
|
|
if len(rv) > 0 {
|
|
t.Fatalf("decrementVersion(%q) - Expected empty string but Got %s", c.kubeVersion, rv)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetYamlFilesFromDir(t *testing.T) {
|
|
cfgDir, err := os.MkdirTemp("", "kube-bench-test")
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp directory")
|
|
}
|
|
defer os.RemoveAll(cfgDir)
|
|
|
|
d := filepath.Join(cfgDir, "cis-1.4")
|
|
err = os.Mkdir(d, 0766)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create temp dir")
|
|
}
|
|
|
|
err = os.WriteFile(filepath.Join(d, "something.yaml"), []byte("hello world"), 0666)
|
|
if err != nil {
|
|
t.Fatalf("error writing file %v", err)
|
|
}
|
|
err = os.WriteFile(filepath.Join(d, "config.yaml"), []byte("hello world"), 0666)
|
|
if err != nil {
|
|
t.Fatalf("error writing file %v", err)
|
|
}
|
|
|
|
files, err := getYamlFilesFromDir(d)
|
|
if err != nil {
|
|
t.Fatalf("Unexpected error: %v", err)
|
|
}
|
|
if len(files) != 1 {
|
|
t.Fatalf("Expected to find one file, found %d", len(files))
|
|
}
|
|
|
|
if files[0] != filepath.Join(d, "something.yaml") {
|
|
t.Fatalf("Expected to find something.yaml, found %s", files[0])
|
|
}
|
|
}
|
|
|
|
func Test_getPlatformNameFromKubectlOutput(t *testing.T) {
|
|
type args struct {
|
|
s string
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want Platform
|
|
}{
|
|
{
|
|
name: "eks",
|
|
args: args{s: "v1.17.9-eks-4c6976"},
|
|
want: Platform{Name: "eks", Version: "1.17"},
|
|
},
|
|
{
|
|
name: "gke",
|
|
args: args{s: "v1.17.6-gke.1"},
|
|
want: Platform{Name: "gke", Version: "1.17"},
|
|
},
|
|
{
|
|
name: "ack",
|
|
args: args{s: "v1.18.8-aliyun.1"},
|
|
want: Platform{Name: "aliyun", Version: "1.18"},
|
|
},
|
|
{
|
|
name: "unknown",
|
|
args: args{s: "v1.17.6"},
|
|
want: Platform{},
|
|
},
|
|
{
|
|
name: "empty string",
|
|
args: args{s: ""},
|
|
want: Platform{},
|
|
},
|
|
{
|
|
name: "k3s",
|
|
args: args{s: "v1.27.6+k3s1"},
|
|
want: Platform{Name: "k3s", Version: "1.27"},
|
|
},
|
|
{
|
|
name: "rancher1",
|
|
args: args{s: "v1.25.13-rancher1-1"},
|
|
want: Platform{Name: "rancher1", Version: "1.25"},
|
|
},
|
|
{
|
|
name: "rke2",
|
|
args: args{s: "v1.27.6+rke2r1"},
|
|
want: Platform{Name: "rke2r", Version: "1.27"},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := getPlatformInfoFromVersion(tt.args.s)
|
|
assert.Equal(t, tt.want, got)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getPlatformBenchmarkVersion(t *testing.T) {
|
|
type args struct {
|
|
platform Platform
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
args args
|
|
want string
|
|
}{
|
|
{
|
|
name: "eks",
|
|
args: args{
|
|
platform: Platform{Name: "eks"},
|
|
},
|
|
want: "eks-1.2.0",
|
|
},
|
|
{
|
|
name: "gke 1.19",
|
|
args: args{
|
|
platform: Platform{Name: "gke", Version: "1.19"},
|
|
},
|
|
want: "gke-1.0",
|
|
},
|
|
{
|
|
name: "gke 1.20",
|
|
args: args{
|
|
platform: Platform{Name: "gke", Version: "1.20"},
|
|
},
|
|
want: "gke-1.2.0",
|
|
},
|
|
{
|
|
name: "gke 1.22",
|
|
args: args{
|
|
platform: Platform{Name: "gke", Version: "1.22"},
|
|
},
|
|
want: "gke-1.2.0",
|
|
},
|
|
{
|
|
name: "aliyun",
|
|
args: args{
|
|
platform: Platform{Name: "aliyun"},
|
|
},
|
|
want: "ack-1.0",
|
|
},
|
|
{
|
|
name: "unknown",
|
|
args: args{
|
|
platform: Platform{Name: "rh"},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "empty",
|
|
args: args{
|
|
platform: Platform{},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "openshift3",
|
|
args: args{
|
|
platform: Platform{Name: "ocp", Version: "3.10"},
|
|
},
|
|
want: "rh-0.7",
|
|
},
|
|
{
|
|
name: "openshift4",
|
|
args: args{
|
|
platform: Platform{Name: "ocp", Version: "4.1"},
|
|
},
|
|
want: "rh-1.0",
|
|
},
|
|
{
|
|
name: "k3s",
|
|
args: args{
|
|
platform: Platform{Name: "k3s", Version: "1.27"},
|
|
},
|
|
want: "k3s-cis-1.7",
|
|
},
|
|
{
|
|
name: "rancher1",
|
|
args: args{
|
|
platform: Platform{Name: "rancher", Version: "1.27"},
|
|
},
|
|
want: "rke-cis-1.7",
|
|
},
|
|
{
|
|
name: "rke2",
|
|
args: args{
|
|
platform: Platform{Name: "rke2r", Version: "1.27"},
|
|
},
|
|
want: "rke2-cis-1.7",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if got := getPlatformBenchmarkVersion(tt.args.platform); got != tt.want {
|
|
t.Errorf("getPlatformBenchmarkVersion() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getOcpValidVersion(t *testing.T) {
|
|
cases := []struct {
|
|
openShiftVersion string
|
|
succeed bool
|
|
exp string
|
|
}{
|
|
{openShiftVersion: "3.11", succeed: true, exp: "3.10"},
|
|
{openShiftVersion: "3.10", succeed: true, exp: "3.10"},
|
|
{openShiftVersion: "2.9", succeed: false, exp: ""},
|
|
{openShiftVersion: "4.1", succeed: true, exp: "4.1"},
|
|
{openShiftVersion: "4.5", succeed: true, exp: "4.1"},
|
|
{openShiftVersion: "4.6", succeed: true, exp: "4.1"},
|
|
{openShiftVersion: "invalid", succeed: false, exp: ""},
|
|
}
|
|
for _, c := range cases {
|
|
ocpVer, _ := getOcpValidVersion(c.openShiftVersion)
|
|
if c.succeed {
|
|
if c.exp != ocpVer {
|
|
t.Errorf("getOcpValidVersion(%q) - Got %q expected %s", c.openShiftVersion, ocpVer, c.exp)
|
|
}
|
|
} else {
|
|
if len(ocpVer) > 0 {
|
|
t.Errorf("getOcpValidVersion(%q) - Expected empty string but Got %s", c.openShiftVersion, ocpVer)
|
|
}
|
|
}
|
|
}
|
|
}
|