diff --git a/.goreleaser.yml b/.goreleaser.yml index 8ab25df61..9ef0f784e 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,5 +1,7 @@ builds: - binary: sonobuoy + env: + - CGO_ENABLED=0 goos: - windows - darwin @@ -8,6 +10,6 @@ builds: - amd64 ldflags: -s -w -X github.com/heptio/sonobuoy/pkg/buildinfo.Version=v{{.Version}} archive: - format: tar.gz + format: tar.gz files: - LICENSE diff --git a/Dockerfile b/Dockerfile index aa9e84bc3..b3966eaea 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM gcr.io/heptio-images/golang:1.9-alpine3.6 +FROM golang:1.9-alpine3.6 MAINTAINER Timothy St. Clair "tstclair@heptio.com" -RUN apk add --no-cache ca-certificates +RUN apk add --no-cache ca-certificates bash ADD sonobuoy /sonobuoy ADD scripts/run_master.sh /run_master.sh ADD scripts/run_single_node_worker.sh /run_single_node_worker.sh diff --git a/Makefile b/Makefile index 095320eab..aae7a7d26 100644 --- a/Makefile +++ b/Makefile @@ -29,14 +29,14 @@ ifneq ($(VERBOSE),) VERBOSE_FLAG = -v endif BUILDMNT = /go/src/$(GOTARGET) -BUILD_IMAGE ?= gcr.io/heptio-images/golang:1.9-alpine3.6 -BUILDCMD = go build -o $(TARGET) $(VERBOSE_FLAG) -ldflags "-X github.com/heptio/sonobuoy/pkg/buildinfo.Version=$(GIT_VERSION)" +BUILD_IMAGE ?= golang:1.9-alpine3.6 +BUILDCMD = CGO_ENABLED=0 go build -o $(TARGET) $(VERBOSE_FLAG) -ldflags "-X github.com/heptio/sonobuoy/pkg/buildinfo.Version=$(GIT_VERSION)" BUILD = $(BUILDCMD) $(GOTARGET) TESTARGS ?= $(VERBOSE_FLAG) -timeout 60s TEST_PKGS ?= $(GOTARGET)/cmd/... $(GOTARGET)/pkg/... TEST_CMD = go test $(TESTARGS) -TEST = $(TEST_CMD) $(TEST_PKGS) +TEST = $(TEST_CMD) $(TEST_PKGS) INT_TEST_PKGS ?= $(GOTARGET)/test/... INT_TEST= $(TEST_CMD) $(INT_TEST_PKGS) @@ -50,19 +50,19 @@ LINT = golint $(GOLINT_FLAGS) $(TEST_PKGS) WORKDIR ?= /sonobuoy DOCKER_BUILD ?= $(DOCKER) run --rm -v $(DIR):$(BUILDMNT) -w $(BUILDMNT) $(BUILD_IMAGE) /bin/sh -c -.PHONY: all container push clean cbuild test local-test local generate plugins int +.PHONY: all container push clean test local-test local generate plugins int all: container -local-test: +local-test: $(TEST) -# Unit tests -test: cbuild vet +# Unit tests +test: sonobuoy vet $(DOCKER_BUILD) '$(TEST)' # Integration tests -int: cbuild +int: sonobuoy $(DOCKER_BUILD) '$(INT_TEST)' lint: @@ -71,14 +71,14 @@ lint: vet: $(DOCKER_BUILD) '$(VET)' -container: +container: sonobuoy $(DOCKER) build \ -t $(REGISTRY)/$(TARGET):$(IMAGE_VERSION) \ -t $(REGISTRY)/$(TARGET):$(IMAGE_BRANCH) \ -t $(REGISTRY)/$(TARGET):$(GIT_REF) \ . -cbuild: +sonobuoy: $(DOCKER_BUILD) '$(BUILD)' push: diff --git a/README.md b/README.md index d6ccced02..9b0f92630 100644 --- a/README.md +++ b/README.md @@ -172,8 +172,8 @@ welcome pull requests. Feel free to dig through the [issues][issue] and jump in. * There is a [mailing list][list] and [Slack channel][slack] if you want to interact with other members of the community -[coc]: https://github.com/heptio/sonobuoy/blob/master/CONTRIBUTING.md -[contrib]: https://github.com/heptio/sonobuoy/blob/master/CODE_OF_CONDUCT.md +[coc]: https://github.com/heptio/sonobuoy/blob/master/CODE_OF_CONDUCT.md +[contrib]: https://github.com/heptio/sonobuoy/blob/master/CONTRIBUTING.md [list]: https://groups.google.com/forum/#!forum/heptio-sonobuoy [slack]: https://kubernetes.slack.com/messages/sonobuoy diff --git a/cmd/sonobuoy/app/e2e.go b/cmd/sonobuoy/app/e2e.go index a9943ae75..3f6a8ccc4 100644 --- a/cmd/sonobuoy/app/e2e.go +++ b/cmd/sonobuoy/app/e2e.go @@ -26,6 +26,7 @@ import ( "github.com/pkg/errors" "github.com/spf13/cobra" "github.com/spf13/pflag" + "k8s.io/client-go/rest" ) type e2eFlags struct { @@ -75,11 +76,17 @@ func e2es(cmd *cobra.Command, args []string) { os.Exit(1) } defer gzr.Close() - restConfig, err := e2eflags.kubecfg.Get() - if err != nil { - errlog.LogError(errors.Wrap(err, "couldn't get REST client")) - os.Exit(1) + + var restConfig *rest.Config + // If we are doing a rerun, only then, we need kubeconfig + if e2eflags.rerun { + restConfig, err = e2eflags.kubecfg.Get() + if err != nil { + errlog.LogError(errors.Wrap(err, "couldn't get REST client")) + os.Exit(1) + } } + sonobuoy, err := client.NewSonobuoyClient(restConfig) if err != nil { errlog.LogError(errors.Wrap(err, "could not create sonobuoy client")) @@ -105,7 +112,10 @@ func e2es(cmd *cobra.Command, args []string) { } if !e2eflags.skipPreflight { - if errs := sonobuoy.PreflightChecks(&client.PreflightConfig{e2eflags.namespace}); len(errs) > 0 { + errs := sonobuoy.PreflightChecks(&client.PreflightConfig{ + Namespace: e2eflags.namespace, + }) + if len(errs) > 0 { errlog.LogError(errors.New("Preflight checks failed")) for _, err := range errs { errlog.LogError(err) diff --git a/cmd/sonobuoy/app/gen.go b/cmd/sonobuoy/app/gen.go index 64399879b..6510ce52b 100644 --- a/cmd/sonobuoy/app/gen.go +++ b/cmd/sonobuoy/app/gen.go @@ -95,12 +95,9 @@ func genManifest(cmd *cobra.Command, args []string) { errlog.LogError(err) os.Exit(1) } - kubeCfg, err := genflags.kubecfg.Get() - if err != nil { - errlog.LogError(errors.Wrap(err, "couldn't get kubernetes config")) - os.Exit(1) - } - sbc, err := client.NewSonobuoyClient(kubeCfg) + // Passing in `nil` and no `kubeconfig` because it is not required by the method + // for generating any manifests + sbc, err := client.NewSonobuoyClient(nil) if err != nil { errlog.LogError(errors.Wrap(err, "could not create sonobuoy client")) os.Exit(1) diff --git a/cmd/sonobuoy/app/rbac.go b/cmd/sonobuoy/app/rbac.go index 8aadd5d45..0b63a2336 100644 --- a/cmd/sonobuoy/app/rbac.go +++ b/cmd/sonobuoy/app/rbac.go @@ -105,7 +105,7 @@ func checkRBACEnabled(client rest.Interface) (bool, error) { groups, ok := result.(*metav1.APIGroupList) if !ok { - return false, fmt.Errorf("Unknown type for API group %t", groups) + return false, fmt.Errorf("Unknown type for API group %T", groups) } for _, group := range groups.Groups { diff --git a/cmd/sonobuoy/app/sonobuoyconfig.go b/cmd/sonobuoy/app/sonobuoyconfig.go index 070b8beba..8331471e0 100644 --- a/cmd/sonobuoy/app/sonobuoyconfig.go +++ b/cmd/sonobuoy/app/sonobuoyconfig.go @@ -20,6 +20,8 @@ import ( "encoding/json" "io/ioutil" + "github.com/imdario/mergo" + "github.com/heptio/sonobuoy/pkg/client" "github.com/heptio/sonobuoy/pkg/config" "github.com/pkg/errors" @@ -68,18 +70,25 @@ func (c *SonobuoyConfig) Get() *config.Config { } // GetConfigWithMode creates a config with the following algorithm: -// If the SonobuoyConfig isn't nil, use that -// If not, use the supplied Mode to modify a default config +// If no config is supplied defaults will be returned. +// If a config is supplied then the default values will be merged into the supplied config +// in order to allow users to supply a minimal config that will still work. func GetConfigWithMode(sonobuoyCfg *SonobuoyConfig, mode client.Mode) *config.Config { + conf := config.New() + suppliedConfig := sonobuoyCfg.Get() if suppliedConfig != nil { - return suppliedConfig + // Provide defaults but don't overwrite any customized configuration. + mergo.Merge(suppliedConfig, conf) + conf = suppliedConfig } - defaultConfig := config.New() - modeConfig := mode.Get() - if modeConfig != nil { - defaultConfig.PluginSelections = modeConfig.Selectors + // if there are no plugins yet, set some based on the mode, otherwise use whatever was supplied. + if len(conf.PluginSelections) == 0 { + modeConfig := mode.Get() + if modeConfig != nil { + conf.PluginSelections = modeConfig.Selectors + } } - return defaultConfig + return conf } diff --git a/cmd/sonobuoy/app/sonobuoyconfig_test.go b/cmd/sonobuoy/app/sonobuoyconfig_test.go new file mode 100644 index 000000000..842834057 --- /dev/null +++ b/cmd/sonobuoy/app/sonobuoyconfig_test.go @@ -0,0 +1,117 @@ +/* +Copyright 2018 Heptio Inc. + +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 app + +import ( + "testing" + + "github.com/heptio/sonobuoy/pkg/client" + "github.com/heptio/sonobuoy/pkg/config" + "github.com/heptio/sonobuoy/pkg/plugin" +) + +func TestGetConfigWithMode(t *testing.T) { + defaultPluginSearchPath := config.New().PluginSearchPath + tcs := []struct { + name string + mode client.Mode + inputcm *SonobuoyConfig + expected *config.Config + }{ + { + name: "Conformance mode when supplied config is nil (nothing interesting happens)", + mode: client.Conformance, + inputcm: &SonobuoyConfig{}, + expected: &config.Config{ + PluginSelections: []plugin.Selection{ + plugin.Selection{Name: "e2e"}, + plugin.Selection{Name: "systemd-logs"}, + }, + PluginSearchPath: defaultPluginSearchPath, + }, + }, + { + name: "Quick mode and a non-nil supplied config", + mode: client.Quick, + inputcm: &SonobuoyConfig{ + Config: config.Config{ + Aggregation: plugin.AggregationConfig{ + BindAddress: "10.0.0.1", + }, + }, + // TODO(chuckha) consider exporting raw or not depending on it. + raw: "not nil", + }, + expected: &config.Config{ + PluginSelections: []plugin.Selection{ + plugin.Selection{Name: "e2e"}, + }, + Aggregation: plugin.AggregationConfig{ + BindAddress: "10.0.0.1", + BindPort: config.DefaultAggregationServerBindPort, + }, + PluginSearchPath: defaultPluginSearchPath, + }, + }, + { + name: "Conformance mode with plugin selection specified", + mode: client.Conformance, + inputcm: &SonobuoyConfig{ + Config: config.Config{ + PluginSelections: []plugin.Selection{ + plugin.Selection{ + Name: "systemd-logs", + }, + }, + }, + raw: "not empty", + }, + expected: &config.Config{ + PluginSelections: []plugin.Selection{ + plugin.Selection{ + Name: "systemd-logs", + }, + }, + PluginSearchPath: defaultPluginSearchPath, + Aggregation: plugin.AggregationConfig{ + BindAddress: config.DefaultAggregationServerBindAddress, + BindPort: config.DefaultAggregationServerBindPort, + }, + }, + }, + } + + for _, tc := range tcs { + t.Run(tc.name, func(t *testing.T) { + conf := GetConfigWithMode(tc.inputcm, tc.mode) + if len(conf.PluginSelections) != len(tc.expected.PluginSelections) { + t.Fatalf("expected %v plugin selections but found %v", tc.expected.PluginSelections, conf.PluginSelections) + } + for _, ps := range conf.PluginSelections { + found := false + for _, expectedPs := range tc.expected.PluginSelections { + if ps.Name == expectedPs.Name { + found = true + } + } + if !found { + t.Fatalf("looking for plugin selection %v but did not find it", ps) + } + } + }) + } +} diff --git a/cmd/sonobuoy/app/status.go b/cmd/sonobuoy/app/status.go index 9ae58ab66..fabd83381 100644 --- a/cmd/sonobuoy/app/status.go +++ b/cmd/sonobuoy/app/status.go @@ -40,7 +40,7 @@ var statusFlags struct { func init() { cmd := &cobra.Command{ Use: "status", - Short: "Gets a summarizes status of a sonobuoy run", + Short: "Gets a summarized status of a sonobuoy run", Run: getStatus, Args: cobra.ExactArgs(0), } diff --git a/docs/release.md b/docs/release.md new file mode 100644 index 000000000..f6baaed8c --- /dev/null +++ b/docs/release.md @@ -0,0 +1,13 @@ +# Release + +## Steps to cut a release + +1. Bump the version defined in the code. As of the time of writing it is in + `pkg/buildinfo/version.go`. +2. Commit and open a pull request. +3. Create a tag after that pull request gets squashed onto master. `git tag -a + v0.11.1`. +4. Push the tag with `git push --tags` (note this will push all tags). To push + just one tag do something like: `git push refs/tags/v0.11.1` where + `` refers to github.com/heptio/sonobuoy (this might be something like + `upstream` or `origin`). If you are unsure, use the first option. diff --git a/pkg/buildinfo/version.go b/pkg/buildinfo/version.go index 5eaaa3437..30213df66 100644 --- a/pkg/buildinfo/version.go +++ b/pkg/buildinfo/version.go @@ -20,7 +20,7 @@ limitations under the License. package buildinfo // Version is the current version of Sonobuoy, set by the go linker's -X flag at build time -var Version = "v0.11.0" +var Version = "v0.11.3" // MinimumKubeVersion is the lowest API version of Kubernetes this release of Sonobuoy supports. var MinimumKubeVersion = "1.8.0" diff --git a/pkg/client/e2e.go b/pkg/client/e2e.go index 07746f377..cfa78c786 100644 --- a/pkg/client/e2e.go +++ b/pkg/client/e2e.go @@ -29,7 +29,7 @@ import ( ) // GetTests extracts the junit results from a sonobuoy archive and returns the requested tests. -func (c *SonobuoyClient) GetTests(reader io.Reader, show string) ([]reporters.JUnitTestCase, error) { +func (*SonobuoyClient) GetTests(reader io.Reader, show string) ([]reporters.JUnitTestCase, error) { read := results.NewReaderWithVersion(reader, "irrelevant") junitResults := reporters.JUnitTestSuite{} err := read.WalkFiles(func(path string, info os.FileInfo, err error) error { diff --git a/pkg/client/gen.go b/pkg/client/gen.go index 1cc482049..c68c0036b 100644 --- a/pkg/client/gen.go +++ b/pkg/client/gen.go @@ -21,12 +21,9 @@ import ( "encoding/json" "strings" - "github.com/imdario/mergo" - "github.com/pkg/errors" "github.com/heptio/sonobuoy/pkg/buildinfo" - "github.com/heptio/sonobuoy/pkg/config" "github.com/heptio/sonobuoy/pkg/templates" ) @@ -45,9 +42,7 @@ type templateValues struct { } // GenerateManifest fills in a template with a Sonobuoy config -func (c *SonobuoyClient) GenerateManifest(cfg *GenConfig) ([]byte, error) { - // Provide defaults but don't overwrite any customized configuration. - mergo.Merge(cfg.Config, config.New()) +func (*SonobuoyClient) GenerateManifest(cfg *GenConfig) ([]byte, error) { marshalledConfig, err := json.Marshal(cfg.Config) if err != nil { return nil, errors.Wrap(err, "couldn't marshall selector") diff --git a/pkg/client/gen_test.go b/pkg/client/gen_test.go index 183027ba1..fcd485fd7 100644 --- a/pkg/client/gen_test.go +++ b/pkg/client/gen_test.go @@ -3,7 +3,7 @@ package client_test import ( "bytes" "encoding/json" - "fmt" + "reflect" "testing" "github.com/heptio/sonobuoy/pkg/client" @@ -21,20 +21,15 @@ func TestGenerateManifest(t *testing.T) { expected *config.Config }{ { - name: "easy", + name: "Defaults in yield a default manifest.", inputcm: &client.GenConfig{ E2EConfig: &client.E2EConfig{}, Config: &config.Config{}, }, - expected: &config.Config{ - Aggregation: plugin.AggregationConfig{ - BindAddress: "0.0.0.0", - BindPort: 8080, - }, - }, + expected: &config.Config{}, }, { - name: "override bind address", + name: "Overriding the bind address", inputcm: &client.GenConfig{ E2EConfig: &client.E2EConfig{}, Config: &config.Config{ @@ -46,12 +41,11 @@ func TestGenerateManifest(t *testing.T) { expected: &config.Config{ Aggregation: plugin.AggregationConfig{ BindAddress: "10.0.0.1", - BindPort: 8080, }, }, }, { - name: "https://github.com/heptio/sonobuoy/issues/390", + name: "Overriding the plugin selection", inputcm: &client.GenConfig{ E2EConfig: &client.E2EConfig{}, Config: &config.Config{ @@ -68,11 +62,21 @@ func TestGenerateManifest(t *testing.T) { Name: "systemd-logs", }, }, - Aggregation: plugin.AggregationConfig{ - BindAddress: "0.0.0.0", - BindPort: 8080, + Aggregation: plugin.AggregationConfig{}, + }, + }, + { + name: "The plugin search path is not modified", + inputcm: &client.GenConfig{ + E2EConfig: &client.E2EConfig{}, + Config: &config.Config{ + PluginSearchPath: []string{"a", "b", "c", "a"}, }, }, + expected: &config.Config{ + Aggregation: plugin.AggregationConfig{}, + PluginSearchPath: []string{"a", "b", "c", "a"}, + }, }, } @@ -101,33 +105,19 @@ func TestGenerateManifest(t *testing.T) { if !ok { t.Fatal("was not a config map...") } - // Ignore everything but the config map we're looking for + + // TODO(chuckha) test other pieces of the generated yaml if cm.ObjectMeta.Name != "sonobuoy-config-cm" { continue } configuration := &config.Config{} - fmt.Println(cm.Data["config.json"]) err = json.Unmarshal([]byte(cm.Data["config.json"]), configuration) if err != nil { t.Errorf("got error %v", err) } - if configuration.UUID == "" { - t.Error("Expected UUID to not be empty") - } - if configuration.Aggregation.BindAddress != tc.expected.Aggregation.BindAddress { - t.Errorf("Expected %v but got %v", tc.expected.Aggregation.BindAddress, configuration.Aggregation.BindAddress) - } - if configuration.Aggregation.BindPort != tc.expected.Aggregation.BindPort { - t.Errorf("Expected %v but got %v", tc.expected.Aggregation.BindPort, configuration.Aggregation.BindPort) - } - if len(configuration.PluginSelections) != len(tc.expected.PluginSelections) { - t.Fatalf("Expected %v plugins but found %v", len(configuration.PluginSelections), len(tc.expected.PluginSelections)) - } - for i, ps := range configuration.PluginSelections { - if tc.expected.PluginSelections[i] != ps { - t.Fatalf("Expected plugin %v but found plugin %v", tc.expected.PluginSelections[i], ps) - } + if !reflect.DeepEqual(configuration, tc.expected) { + t.Fatalf("Expected %v to equal %v", tc.expected, configuration) } } }) diff --git a/pkg/config/config.go b/pkg/config/config.go index a2c5a70b2..4fa6699b7 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -29,8 +29,12 @@ import ( const ( // DefaultNamespace is the namespace where the master and plugin workers will run (but not necessarily the pods created by the plugin workers). DefaultNamespace = "heptio-sonobuoy" - // DefaultKubeConformanceImage is the URL of the docker image to run for the kube conformance tests + // DefaultKubeConformanceImage is the URL of the docker image to run for the kube conformance tests. DefaultKubeConformanceImage = "gcr.io/heptio-images/kube-conformance:latest" + // DefaultAggregationServerBindPort is the default port for the aggregation server to bind to. + DefaultAggregationServerBindPort = 8080 + // DefaultAggregationServerBindAddress is the default address for the aggregation server to bind to. + DefaultAggregationServerBindAddress = "0.0.0.0" // MasterPodName is the name of the main pod that runs plugins and collects results. MasterPodName = "sonobuoy" // MasterContainerName is the name of the main container in the master pod. @@ -244,8 +248,8 @@ func New() *Config { cfg.Namespace = DefaultNamespace - cfg.Aggregation.BindAddress = "0.0.0.0" - cfg.Aggregation.BindPort = 8080 + cfg.Aggregation.BindAddress = DefaultAggregationServerBindAddress + cfg.Aggregation.BindPort = DefaultAggregationServerBindPort cfg.Aggregation.TimeoutSeconds = 5400 // 90 minutes cfg.PluginSearchPath = []string{ diff --git a/pkg/config/config_test.go b/pkg/config/config_test.go index f4a52bae3..69eeb4f99 100644 --- a/pkg/config/config_test.go +++ b/pkg/config/config_test.go @@ -14,16 +14,18 @@ See the License for the specific language governing permissions and limitations under the License. */ -package config +package config_test import ( "reflect" "testing" + + "github.com/heptio/sonobuoy/pkg/config" ) func TestDefaults(t *testing.T) { - cfg1 := New() - cfg2 := New() + cfg1 := config.New() + cfg2 := config.New() if reflect.DeepEqual(&cfg2, &cfg1) { t.Fatalf("Defaults should not match UUIDs collided") diff --git a/pkg/plugin/loader/loader.go b/pkg/plugin/loader/loader.go index 5c26a40cb..c963859cb 100644 --- a/pkg/plugin/loader/loader.go +++ b/pkg/plugin/loader/loader.go @@ -37,7 +37,7 @@ import ( // address (host:port) and returning all of the active, configured plugins for // this sonobuoy run. func LoadAllPlugins(namespace, sonobuoyImage, imagePullPolicy string, searchPath []string, selections []plugin.Selection) (ret []plugin.Interface, err error) { - pluginDefinitionFiles := []string{} + pluginDefinitionFiles := make(map[string]struct{}) for _, dir := range searchPath { wd, _ := os.Getwd() logrus.Infof("Scanning plugins in %v (pwd: %v)", dir, wd) @@ -53,11 +53,13 @@ func LoadAllPlugins(namespace, sonobuoyImage, imagePullPolicy string, searchPath if err != nil { return []plugin.Interface{}, errors.Wrapf(err, "couldn't scan %v for plugins", dir) } - pluginDefinitionFiles = append(pluginDefinitionFiles, files...) + for _, file := range files { + pluginDefinitionFiles[file] = struct{}{} + } } pluginDefinitions := []*manifest.Manifest{} - for _, file := range pluginDefinitionFiles { + for file := range pluginDefinitionFiles { definitionFile, err := loadDefinitionFromFile(file) if err != nil { return []plugin.Interface{}, errors.Wrapf(err, "couldn't load plugin definition file %v", file) diff --git a/pkg/plugin/loader/loader_test.go b/pkg/plugin/loader/loader_test.go index cdfc71230..e50dd7716 100644 --- a/pkg/plugin/loader/loader_test.go +++ b/pkg/plugin/loader/loader_test.go @@ -192,3 +192,48 @@ func TestFilterList(t *testing.T) { t.Errorf("expected %+#v, got %+#v", expected, filtered) } } + +func TestLoadAllPlugins(t *testing.T) { + testcases := []struct { + testname string + namespace string + sonobuoyImage string + imagePullPolicy string + searchPath []string + selections []plugin.Selection + expectedPluginNames []string + }{ + { + testname: "ensure duplicate paths do not result in duplicate loaded plugins.", + searchPath: []string{path.Join("testdata", "plugin.d"), path.Join("testdata", "plugin.d")}, + selections: []plugin.Selection{ + plugin.Selection{Name: "test-job-plugin"}, + plugin.Selection{Name: "test-daemon-set-plugin"}, + }, + expectedPluginNames: []string{"test-job-plugin", "test-daemon-set-plugin"}, + }, + } + + for _, tc := range testcases { + t.Run(tc.testname, func(t *testing.T) { + plugins, err := LoadAllPlugins(tc.namespace, tc.sonobuoyImage, tc.imagePullPolicy, tc.searchPath, tc.selections) + if err != nil { + t.Fatalf("error loading all plugins: %v", err) + } + if len(plugins) != len(tc.expectedPluginNames) { + t.Fatalf("expected %v plugins but got %v", len(tc.expectedPluginNames), len(plugins)) + } + for i, plugin := range plugins { + found := false + for _, expectedPlugin := range tc.expectedPluginNames { + if plugin.GetName() == expectedPlugin { + found = true + } + } + if !found { + t.Fatalf("Expected %v but got %v", tc.expectedPluginNames[i], plugin.GetName()) + } + } + }) + } +} diff --git a/pkg/tarball/tarball_test.go b/pkg/tarball/tarball_test.go index 966b018fc..f5feb7a65 100644 --- a/pkg/tarball/tarball_test.go +++ b/pkg/tarball/tarball_test.go @@ -104,7 +104,7 @@ func TestDecodeTarball(t *testing.T) { rBuffer := bytes.NewBuffer(buffer.Bytes()) - file, err := os.Open(path.Join("test_data/archive.tar.gz")) + file, err := os.Open(path.Join("testdata/archive.tar.gz")) if err != nil { t.Fatalf("couldn't extract archive: %v", err) } diff --git a/pkg/tarball/test_data/archive.tar.gz b/pkg/tarball/testdata/archive.tar.gz similarity index 100% rename from pkg/tarball/test_data/archive.tar.gz rename to pkg/tarball/testdata/archive.tar.gz diff --git a/travis-deploy.sh b/travis-deploy.sh index ead8419f5..12757021d 100755 --- a/travis-deploy.sh +++ b/travis-deploy.sh @@ -18,7 +18,7 @@ function gcr_push() { if [ ! -z "$TRAVIS_TAG" ]; then - if [ "$(./sonobuoy version)" != "$TRAVIS_TAG"]; then + if [ "$(./sonobuoy version)" != "$TRAVIS_TAG" ]; then echo "sonobuoy version does not match tagged version!" >&2 echo "sonobuoy version is $(./sonobuoy version)" >&2 echo "tag is $TRAVIS_TAG" >&2