Skip to content

Commit

Permalink
Add testcases and refactor few methods to make it testable
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilsbhat committed Nov 20, 2022
1 parent 1be19da commit 1505bb3
Show file tree
Hide file tree
Showing 9 changed files with 355 additions and 59 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
/vendor
helm-images
/dist
cover.out
cover.out
cover.html
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ help: ## Prints help (only for targets with comments)
@grep -E '^[a-zA-Z0-9._-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

local.fmt: ## Lints all the go code in the application.
gofmt -w $(GOFMT_FILES)
@gofmt -w $(GOFMT_FILES)
$(GOBIN)/goimports -w $(GOFMT_FILES)
$(GOBIN)/gofumpt -l -w $(GOFMT_FILES)
$(GOBIN)/gci write $(GOFMT_FILES) --skip-generated

local.check: local.fmt ## Loads all the dependencies to vendor directory
go mod vendor
go mod tidy
@go mod vendor
@go mod tidy

local.build: local.check ## Generates the artifact with the help of 'go build'
GOVERSION=${GOVERSION} BUILD_ENVIRONMENT=${BUILD_ENVIRONMENT} goreleaser build --rm-dist
Expand Down Expand Up @@ -65,4 +65,4 @@ generate.mock: ## generates mocks for the selected source packages.
@go generate ${SRC_PACKAGES}

test: ## runs test cases
go test ./... -mod=vendor -coverprofile cover.out
@go test ./... -mod=vendor -coverprofile cover.out && go tool cover -html=cover.out -o cover.html && open cover.html
1 change: 1 addition & 0 deletions cmd/register.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func getImagesCommand() *cobra.Command {
Args: minimumArgError,
RunE: func(cmd *cobra.Command, args []string) error {
images.SetLogger(images.LogLevel)
images.SetWriter(os.Stdout)
cmd.SilenceUsage = true

images.SetRelease(args[0])
Expand Down
206 changes: 206 additions & 0 deletions pkg/filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
package pkg

import (
"testing"

"github.com/nikhilsbhat/helm-images/pkg/k8s"
"github.com/stretchr/testify/assert"
)

func TestImages_filterImagesByRegistries(t *testing.T) {
t.Run("should be able to return the filtered images by registries", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{
Registries: []string{"quay.io", "k8s.gcr.io"},
}
imageClient.SetLogger("info")

expectedImageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
},
}

expected := []*k8s.Image{&expectedImageKind}

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.ElementsMatch(t, expected[0].Image, imagesFiltered[0].Image)
})

t.Run("should be able to return the filtered images by registries", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{
Registries: []string{"qquay.io"},
}

imageClient.SetLogger("info")

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.Nil(t, imagesFiltered)
})

t.Run("should be able to return the filtered unique images by registries", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{
Registries: []string{"quay.io"},
UniqueImages: true,
}

imageClient.SetLogger("info")

expectedImageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"quay.io/prometheus/alertmanager:v0.21.0",
},
}
expected := []*k8s.Image{&expectedImageKind}

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.Equal(t, expected, imagesFiltered)
})

t.Run("should be image list as it is as no registries matched", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{}

imageClient.SetLogger("info")

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.ElementsMatch(t, imageList[0].Image, imagesFiltered[0].Image)
})

t.Run("should be able to return the unique and not filtered images by registries", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{
UniqueImages: true,
}
imageClient.SetLogger("info")

expectedImageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

expected := []*k8s.Image{&expectedImageKind}

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.ElementsMatch(t, expected[0].Image, imagesFiltered[0].Image)
})
}

func Test_filteredImages(t *testing.T) {
t.Run("should be able to filter the images by the list of registries", func(t *testing.T) {
images := []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
}
registries := []string{"quay.io"}

expected := []string{
"quay.io/prometheus/alertmanager:v0.21.0",
"quay.io/prometheus/node-exporter:v1.1.2",
}

actual := filteredImages(images, registries)
assert.ElementsMatch(t, actual, expected)
})

t.Run("should be able to filter the images by the list of registries with matching names", func(t *testing.T) {
images := []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
}
registries := []string{"quay"}

expected := []string{
"quay.io/prometheus/alertmanager:v0.21.0",
"quay.io/prometheus/node-exporter:v1.1.2",
}

actual := filteredImages(images, registries)
assert.ElementsMatch(t, actual, expected)
})
}
7 changes: 7 additions & 0 deletions pkg/images.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package pkg

import (
"bufio"
"fmt"
"io"
"io/fs"
"os"
"os/exec"
Expand Down Expand Up @@ -38,6 +40,7 @@ type Images struct {
release string
chart string
log *logrus.Logger
writer *bufio.Writer
}

func (image *Images) SetRelease(release string) {
Expand All @@ -48,6 +51,10 @@ func (image *Images) SetChart(chart string) {
image.chart = chart
}

func (image *Images) SetWriter(writer io.Writer) {
image.writer = bufio.NewWriter(writer)
}

// GetImages fetches all available images from the specified chart.
// Also filters identified images, to get just unique ones.
func (image *Images) GetImages() error {
Expand Down
77 changes: 35 additions & 42 deletions pkg/images_test.go
Original file line number Diff line number Diff line change
@@ -1,54 +1,18 @@
package pkg

import (
"os"
"testing"

"github.com/nikhilsbhat/helm-images/pkg/k8s"
"github.com/stretchr/testify/assert"
)

func TestImages_filterImages(t *testing.T) {
t.Run("should be able to return the filtered image list", func(t *testing.T) {
imageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
"prom/pushgateway:v1.3.1",
"jimmidyson/configmap-reload:v0.5.0",
},
}

imageList := []*k8s.Image{&imageKind}

imageClient := Images{
Registries: []string{"quay.io", "k8s.gcr.io"},
}
imageClient.SetLogger("info")

expectedImageKind := k8s.Image{
Kind: "Deployment",
Name: "sample-deployment",
Image: []string{
"quay.io/prometheus/node-exporter:v1.1.2",
"k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.0.0",
"quay.io/prometheus/alertmanager:v0.21.0",
},
}

expected := []*k8s.Image{&expectedImageKind}

imagesFiltered := imageClient.filterImagesByRegistries(imageList)
assert.ElementsMatch(t, expected[0].Image, imagesFiltered[0].Image)
})
}

func Test_getImages(t *testing.T) {
imageClient := Images{
ImageRegex: ImageRegex,
}
imageClient.SetLogger("info")
helmTemplate := `
---
# Source: prometheus/charts/prometheus/templates/alertmanager/clusterrole.yaml
Expand Down Expand Up @@ -121,12 +85,14 @@ data:

t.Run("should be able to split rendered templates to individual templates", func(t *testing.T) {
expected := []string{
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n labels:\n component: \"alertmanager\"\n app: prometheus\n release: prometheus-standalone\n chart: prometheus-14.4.1\n heritage: Helm\n name: prometheus-standalone-alertmanager\nrules:\n []\n", //nolint:lll
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n labels:\n component: \"pushgateway\"\n app: prometheus\n release: prometheus-standalone\n chart: prometheus-14.4.1\n heritage: Helm\n name: prometheus-standalone-pushgateway\nrules:\n []\n", //nolint:lll
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n app.kubernetes.io/name: kube-state-metrics\n helm.sh/chart: kube-state-metrics-3.1.1\n app.kubernetes.io/managed-by: Helm\n app.kubernetes.io/instance: prometheus-standalone\n name: prometheus-standalone-kube-state-metrics\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus-standalone-kube-state-metrics\nsubjects:\n- kind: ServiceAccount\n name: prometheus-standalone-kube-state-metrics\n namespace: test\n", //nolint:lll
"\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: jaeger-ca-cert\ndata:\n CA_CERTIFICATE: |\n -----BEGIN CERTIFICATE-----\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n -----END CERTIFICATE-----\n", //nolint:lll
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n labels:\n component: \"alertmanager\"\n app: prometheus\n release: prometheus-standalone\n chart: prometheus-14.4.1\n heritage: Helm\n name: prometheus-standalone-alertmanager\nrules:\n []\n", //nolint:lll
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRole\nmetadata:\n labels:\n component: \"pushgateway\"\n app: prometheus\n release: prometheus-standalone\n chart: prometheus-14.4.1\n heritage: Helm\n name: prometheus-standalone-pushgateway\nrules:\n []\n", //nolint:lll
"\napiVersion: rbac.authorization.k8s.io/v1\nkind: ClusterRoleBinding\nmetadata:\n labels:\n app.kubernetes.io/name: kube-state-metrics\n helm.sh/chart: kube-state-metrics-3.1.1\n app.kubernetes.io/managed-by: Helm\n app.kubernetes.io/instance: prometheus-standalone\n name: prometheus-standalone-kube-state-metrics\nroleRef:\n apiGroup: rbac.authorization.k8s.io\n kind: ClusterRole\n name: prometheus-standalone-kube-state-metrics\nsubjects:\n- kind: ServiceAccount\n name: prometheus-standalone-kube-state-metrics\n namespace: test\n", //nolint:lll
"\napiVersion: v1\nkind: ConfigMap\nmetadata:\n name: jaeger-ca-cert\ndata:\n CA_CERTIFICATE: |\n -----BEGIN CERTIFICATE-----\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n\t\tOCOIRRGVEGHEIGHEnwoircne20394809234nfh834retitneh83t5ljfKHD&$&$\n -----END CERTIFICATE-----\n", //nolint:lll
}
actual := imageClient.getTemplates([]byte(helmTemplate))
assert.Equal(t, len(expected), len(actual))
// assert.Equal(t, sort.StringSlice(expected), sort.StringSlice(actual))
assert.ElementsMatch(t, expected, actual)
})
}
Expand All @@ -148,3 +114,30 @@ func Test_getImagesFromKind(t *testing.T) {
assert.ElementsMatch(t, expected, images)
})
}

func TestImages_SetRelease(t *testing.T) {
t.Run("Should be able to set the release", func(t *testing.T) {
imageClient := Images{}
imageClient.SetRelease("testRelease")

assert.Equal(t, imageClient.release, "testRelease")
})
}

func TestImages_SetChart(t *testing.T) {
t.Run("Should be able to set the chart", func(t *testing.T) {
imageClient := Images{}
imageClient.SetChart("testChart")

assert.Equal(t, imageClient.chart, "testChart")
})
}

func TestImages_SetWriter(t *testing.T) {
t.Run("Should be able to set the writer", func(t *testing.T) {
imageClient := Images{}
imageClient.SetWriter(os.Stdout)

assert.NotNil(t, imageClient.writer)
})
}
Loading

0 comments on commit 1505bb3

Please sign in to comment.