diff --git a/tests/general/discoverymode/k8s_observer_discovery_test.go b/tests/general/discoverymode/k8s_observer_discovery_test.go index 78c8ac4416..5f7af5613b 100644 --- a/tests/general/discoverymode/k8s_observer_discovery_test.go +++ b/tests/general/discoverymode/k8s_observer_discovery_test.go @@ -237,9 +237,7 @@ func configToConfigMapManifest(t testing.TB, cfg, namespace string) (name, manif Name: "collector.config", Namespace: namespace, Data: string(configYaml), } - cmm, err := cm.Render() - require.NoError(t, err) - return cm.Name, cmm + return cm.Name, cm.Render(t) } func clusterRoleAndBindingManifests(t testing.TB, namespace, serviceAccount string) (string, string) { @@ -308,8 +306,6 @@ func clusterRoleAndBindingManifests(t testing.TB, namespace, serviceAccount stri }, }, } - crManifest, err := cr.Render() - require.NoError(t, err) crb := manifests.ClusterRoleBinding{ Namespace: namespace, @@ -317,10 +313,8 @@ func clusterRoleAndBindingManifests(t testing.TB, namespace, serviceAccount stri ClusterRoleName: cr.Name, ServiceAccountName: serviceAccount, } - crbManifest, err := crb.Render() - require.NoError(t, err) - return crManifest, crbManifest + return cr.Render(t), crb.Render(t) } func daemonSetManifest(cluster *kubeutils.KindCluster, namespace, serviceAccount, configMap string) (name, manifest string) { @@ -404,7 +398,5 @@ func daemonSetManifest(cluster *kubeutils.KindCluster, namespace, serviceAccount }, }, } - dsm, err := ds.Render() - require.NoError(cluster.Testcase, err) - return ds.Name, dsm + return ds.Name, ds.Render(cluster.Testcase) } diff --git a/tests/receivers/discovery/k8s_observer_test.go b/tests/receivers/discovery/k8s_observer_test.go index 13fb491b58..0d9862d4ab 100644 --- a/tests/receivers/discovery/k8s_observer_test.go +++ b/tests/receivers/discovery/k8s_observer_test.go @@ -238,9 +238,7 @@ func configToConfigMapManifest(t testing.TB, configPath, namespace string) (name Name: "collector.config", Namespace: namespace, Data: string(configYaml), } - cmm, err := cm.Render() - require.NoError(t, err) - return cm.Name, cmm + return cm.Name, cm.Render(t) } func clusterRoleAndBindingManifests(t testing.TB, namespace, serviceAccount string) (string, string) { @@ -309,19 +307,14 @@ func clusterRoleAndBindingManifests(t testing.TB, namespace, serviceAccount stri }, }, } - crManifest, err := cr.Render() - require.NoError(t, err) - crb := manifests.ClusterRoleBinding{ Namespace: namespace, Name: "cluster-role-binding", ClusterRoleName: cr.Name, ServiceAccountName: serviceAccount, } - crbManifest, err := crb.Render() - require.NoError(t, err) - return crManifest, crbManifest + return cr.Render(t), crb.Render(t) } func daemonSetManifest(cluster *kubeutils.KindCluster, namespace, serviceAccount, configMap string) (name, manifest string) { @@ -375,7 +368,5 @@ func daemonSetManifest(cluster *kubeutils.KindCluster, namespace, serviceAccount }, }, } - dsm, err := ds.Render() - require.NoError(cluster.Testcase, err) - return ds.Name, dsm + return ds.Name, ds.Render(cluster.Testcase) } diff --git a/tests/receivers/smartagent/collectd-mysql/bundled_test.go b/tests/receivers/smartagent/collectd-mysql/bundled_test.go index 914782fe81..dc97c66271 100644 --- a/tests/receivers/smartagent/collectd-mysql/bundled_test.go +++ b/tests/receivers/smartagent/collectd-mysql/bundled_test.go @@ -223,10 +223,7 @@ service: Name: "collector.config", Data: string(data), } - cmm, err := cm.Render() - require.NoError(cluster.Testcase, err) - - sout, serr, err := cluster.Apply(cmm) + sout, serr, err := cluster.Apply(cm.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ConfigMap", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) return cm.Name @@ -298,9 +295,7 @@ func (cluster testCluster) createClusterRoleAndRoleBinding(namespace, serviceAcc }, }, } - crManifest, err := cr.Render() - require.NoError(cluster.Testcase, err) - sout, serr, err := cluster.Apply(crManifest) + sout, serr, err := cluster.Apply(cr.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ClusterRole", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) @@ -310,10 +305,7 @@ func (cluster testCluster) createClusterRoleAndRoleBinding(namespace, serviceAcc ClusterRoleName: cr.Name, ServiceAccountName: serviceAccount, } - crbManifest, err := crb.Render() - require.NoError(cluster.Testcase, err) - - sout, serr, err = cluster.Apply(crbManifest) + sout, serr, err = cluster.Apply(crb.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ClusterRoleBinding", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) } @@ -381,9 +373,7 @@ func (cluster testCluster) daemonSetManifest(namespace, serviceAccount, configMa }, }, } - dsm, err := ds.Render() - require.NoError(cluster.Testcase, err) - sout, serr, err := cluster.Apply(dsm) + sout, serr, err := cluster.Apply(ds.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying DaemonSet", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) return ds.Name diff --git a/tests/receivers/smartagent/postgresql/bundled_test.go b/tests/receivers/smartagent/postgresql/bundled_test.go index 2c104ca340..00ede8be61 100644 --- a/tests/receivers/smartagent/postgresql/bundled_test.go +++ b/tests/receivers/smartagent/postgresql/bundled_test.go @@ -110,9 +110,7 @@ func (cluster testCluster) createPostgres(name, namespace, serviceAccount string Name: "postgres", Data: string(configMapContent), } - cmm, err := cm.Render() - require.NoError(cluster.Testcase, err) - sout, serr, err := cluster.Apply(cmm) + sout, serr, err := cluster.Apply(cm.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ConfigMap", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) @@ -283,10 +281,7 @@ service: Name: "collector.config", Data: string(data), } - cmm, err := cm.Render() - require.NoError(cluster.Testcase, err) - - sout, serr, err := cluster.Apply(cmm) + sout, serr, err := cluster.Apply(cm.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ConfigMap", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) return cm.Name @@ -358,9 +353,7 @@ func (cluster testCluster) createClusterRoleAndRoleBinding(namespace, serviceAcc }, }, } - crManifest, err := cr.Render() - require.NoError(cluster.Testcase, err) - sout, serr, err := cluster.Apply(crManifest) + sout, serr, err := cluster.Apply(cr.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ClusterRole", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) @@ -370,10 +363,7 @@ func (cluster testCluster) createClusterRoleAndRoleBinding(namespace, serviceAcc ClusterRoleName: cr.Name, ServiceAccountName: serviceAccount, } - crbManifest, err := crb.Render() - require.NoError(cluster.Testcase, err) - - sout, serr, err = cluster.Apply(crbManifest) + sout, serr, err = cluster.Apply(crb.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying ClusterRoleBinding", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) } @@ -440,9 +430,7 @@ func (cluster testCluster) daemonSetManifest(namespace, serviceAccount, configMa }, }, } - dsm, err := ds.Render() - require.NoError(cluster.Testcase, err) - sout, serr, err := cluster.Apply(dsm) + sout, serr, err := cluster.Apply(ds.Render(cluster.Testcase)) cluster.Testcase.Logger.Debug("applying DaemonSet", zap.String("stdout", sout.String()), zap.String("stderr", serr.String())) require.NoError(cluster.Testcase, err) return ds.Name diff --git a/tests/testutils/kubeutils/manifests/cluster_role.go b/tests/testutils/kubeutils/manifests/cluster_role.go index 28e58e6fb7..3880bd59f7 100644 --- a/tests/testutils/kubeutils/manifests/cluster_role.go +++ b/tests/testutils/kubeutils/manifests/cluster_role.go @@ -16,6 +16,8 @@ package manifests import ( + "testing" + rbacv1 "k8s.io/api/rbac/v1" ) @@ -51,6 +53,6 @@ rules: var crm = Manifest[ClusterRole](clusterRoleTemplate) -func (cr ClusterRole) Render() (string, error) { - return crm.Render(cr) +func (cr ClusterRole) Render(t testing.TB) string { + return crm.Render(cr, t) } diff --git a/tests/testutils/kubeutils/manifests/cluster_role_binding.go b/tests/testutils/kubeutils/manifests/cluster_role_binding.go index 17ba88e2f6..f3ec8eb3f9 100644 --- a/tests/testutils/kubeutils/manifests/cluster_role_binding.go +++ b/tests/testutils/kubeutils/manifests/cluster_role_binding.go @@ -16,6 +16,8 @@ package manifests import ( + "testing" + rbacv1 "k8s.io/api/rbac/v1" ) @@ -70,6 +72,6 @@ subjects: var crbm = Manifest[ClusterRoleBinding](clusterRoleBindingTemplate) -func (crb ClusterRoleBinding) Render() (string, error) { - return crbm.Render(crb) +func (crb ClusterRoleBinding) Render(t testing.TB) string { + return crbm.Render(crb, t) } diff --git a/tests/testutils/kubeutils/manifests/cluster_role_binding_test.go b/tests/testutils/kubeutils/manifests/cluster_role_binding_test.go index 0a87e8f117..54ff665b3c 100644 --- a/tests/testutils/kubeutils/manifests/cluster_role_binding_test.go +++ b/tests/testutils/kubeutils/manifests/cluster_role_binding_test.go @@ -31,8 +31,7 @@ func TestClusterRoleBinding(t *testing.T) { ClusterRoleName: "some.cluster.role", ServiceAccountName: "some.service.account", } - manifest, err := crb.Render() - require.NoError(t, err) + manifest := crb.Render(t) require.Equal(t, `--- apiVersion: rbac.authorization.k8s.io/v1 @@ -71,8 +70,7 @@ func TestClusterRoleBindingWithRoleRefAndSubjects(t *testing.T) { }, }, } - manifest, err := crb.Render() - require.NoError(t, err) + manifest := crb.Render(t) require.Equal(t, `--- apiVersion: rbac.authorization.k8s.io/v1 @@ -94,8 +92,7 @@ subjects: func TestEmptyClusterRoleBinding(t *testing.T) { crb := ClusterRoleBinding{} - manifest, err := crb.Render() - require.NoError(t, err) + manifest := crb.Render(t) require.Equal(t, `--- apiVersion: rbac.authorization.k8s.io/v1 diff --git a/tests/testutils/kubeutils/manifests/cluster_role_test.go b/tests/testutils/kubeutils/manifests/cluster_role_test.go index 695a515dd2..822105d11d 100644 --- a/tests/testutils/kubeutils/manifests/cluster_role_test.go +++ b/tests/testutils/kubeutils/manifests/cluster_role_test.go @@ -91,8 +91,6 @@ func TestClusterRole(t *testing.T) { }, }, } - manifest, err := cr.Render() - require.NoError(t, err) require.Equal(t, `--- apiVersion: rbac.authorization.k8s.io/v1 @@ -167,17 +165,15 @@ rules: - get - list - watch -`, manifest) +`, cr.Render(t)) } func TestEmptyClusterRole(t *testing.T) { cr := ClusterRole{} - manifest, err := cr.Render() - require.NoError(t, err) require.Equal(t, `--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: -`, manifest) +`, cr.Render(t)) } diff --git a/tests/testutils/kubeutils/manifests/config_map.go b/tests/testutils/kubeutils/manifests/config_map.go index 2906b27706..82fccf94a8 100644 --- a/tests/testutils/kubeutils/manifests/config_map.go +++ b/tests/testutils/kubeutils/manifests/config_map.go @@ -15,6 +15,8 @@ package manifests +import "testing" + type ConfigMap struct { Namespace string Name string @@ -39,6 +41,6 @@ data: var cmm = Manifest[ConfigMap](configMapTemplate) -func (cm ConfigMap) Render() (string, error) { - return cmm.Render(cm) +func (cm ConfigMap) Render(t testing.TB) string { + return cmm.Render(cm, t) } diff --git a/tests/testutils/kubeutils/manifests/config_map_test.go b/tests/testutils/kubeutils/manifests/config_map_test.go index 9504e14160..26beeb7d85 100644 --- a/tests/testutils/kubeutils/manifests/config_map_test.go +++ b/tests/testutils/kubeutils/manifests/config_map_test.go @@ -34,8 +34,7 @@ func TestConfigMap(t *testing.T) { nested.key.two: nested.value.two`, } - manifest, err := cm.Render() - require.NoError(t, err) + manifest := cm.Render(t) require.Equal(t, `--- apiVersion: v1 @@ -54,8 +53,7 @@ data: func TestEmptyConfigMap(t *testing.T) { cm := ConfigMap{} - manifest, err := cm.Render() - require.NoError(t, err) + manifest := cm.Render(t) require.Equal(t, `--- apiVersion: v1 diff --git a/tests/testutils/kubeutils/manifests/daemon_set.go b/tests/testutils/kubeutils/manifests/daemon_set.go index 723d1c7a4b..6c63137972 100644 --- a/tests/testutils/kubeutils/manifests/daemon_set.go +++ b/tests/testutils/kubeutils/manifests/daemon_set.go @@ -16,6 +16,8 @@ package manifests import ( + "testing" + corev1 "k8s.io/api/core/v1" ) @@ -75,6 +77,6 @@ spec: var dsm = Manifest[DaemonSet](daemonSetTemplate) -func (d DaemonSet) Render() (string, error) { - return dsm.Render(d) +func (d DaemonSet) Render(t testing.TB) string { + return dsm.Render(d, t) } diff --git a/tests/testutils/kubeutils/manifests/daemon_set_test.go b/tests/testutils/kubeutils/manifests/daemon_set_test.go index 327ae43274..3606f1b168 100644 --- a/tests/testutils/kubeutils/manifests/daemon_set_test.go +++ b/tests/testutils/kubeutils/manifests/daemon_set_test.go @@ -71,8 +71,7 @@ func TestDaemonSet(t *testing.T) { }, } - manifest, err := ds.Render() - require.NoError(t, err) + manifest := ds.Render(t) require.Equal(t, `--- apiVersion: apps/v1 @@ -120,8 +119,7 @@ spec: func TestEmptyDaemonSet(t *testing.T) { ds := DaemonSet{} - manifest, err := ds.Render() - require.NoError(t, err) + manifest := ds.Render(t) require.Equal(t, `--- apiVersion: apps/v1 diff --git a/tests/testutils/kubeutils/manifests/deployment.go b/tests/testutils/kubeutils/manifests/deployment.go new file mode 100644 index 0000000000..df0b33fa71 --- /dev/null +++ b/tests/testutils/kubeutils/manifests/deployment.go @@ -0,0 +1,93 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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 manifests + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" +) + +// Deployment is a "k8s.io/api/apps/v1.Deployment" convenience type +type Deployment struct { + Labels map[string]string + MatchLabels map[string]string + Namespace string + Name string + ServiceAccount string + Containers []corev1.Container + Volumes []corev1.Volume + Replicas int +} + +const deploymentTemplate = `--- +apiVersion: apps/v1 +kind: Deployment +metadata: +{{- if .Name }} + name: {{ .Name }} +{{- end -}} +{{- if .Namespace }} + namespace: {{ .Namespace }} +{{- end }} +{{- if .Labels }} + labels: + {{- range $key, $value := .Labels }} + {{ $key }}: {{ $value }} + {{- end }} +{{- end }} +spec: + replicas: {{ .Replicas }} + selector: + matchLabels: +{{- if .Name }} + name: {{ .Name }} +{{- end }} +{{- if .MatchLabels }} + {{- range $key, $value := .MatchLabels }} + {{ $key }}: {{ $value }} + {{- end }} +{{- end }} + template: + metadata: + labels: +{{- if .Name }} + name: {{ .Name }} +{{- end }} +{{- if .MatchLabels }} + {{- range $key, $value := .MatchLabels }} + {{ $key }}: {{ $value }} + {{- end }} +{{- end }} + spec: +{{- if .ServiceAccount }} + serviceAccountName: {{ .ServiceAccount }} +{{- end }} +{{- if .Containers }} + containers: +{{ .Containers | toYaml | indent 6 }} +{{- end }} +{{- if .Volumes }} + volumes: +{{ .Volumes | toYaml | indent 6 }} +{{- end }} +` + +var dm = Manifest[Deployment](deploymentTemplate) + +func (d Deployment) Render(t testing.TB) string { + return dm.Render(d, t) +} diff --git a/tests/testutils/kubeutils/manifests/deployment_test.go b/tests/testutils/kubeutils/manifests/deployment_test.go new file mode 100644 index 0000000000..9a9b5c264e --- /dev/null +++ b/tests/testutils/kubeutils/manifests/deployment_test.go @@ -0,0 +1,125 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build testutils + +package manifests + +import ( + "testing" + + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" +) + +func TestDeployment(t *testing.T) { + dep := Deployment{ + Name: "some.deployment", + Namespace: "some.namespace", + Labels: map[string]string{ + "label.one": "value.one", + "label.two": "value.two", + }, + MatchLabels: map[string]string{ + "match.label.one": "match.value.one", + "match.label.two": "match.value.two", + }, + Replicas: 123, + Containers: []v1.Container{ + { + Name: "a.container", + Image: "an.image", + Env: []v1.EnvVar{ + {Name: "an.env.var", Value: "a.value"}, + }, + }, + { + Name: "another.container", + Image: "another.image", + VolumeMounts: []v1.VolumeMount{ + { + Name: "config-map-volume", MountPath: "/config/map", + }, + }, + }, + }, + ServiceAccount: "some.service.account", + Volumes: []v1.Volume{ + { + Name: "config-map-volume", + VolumeSource: v1.VolumeSource{ + ConfigMap: &v1.ConfigMapVolumeSource{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "some-config-map", + }, + Items: []v1.KeyToPath{ + { + Key: "config", + Path: "config.yaml", + }, + }, + }, + }, + }, + }, + } + + require.Equal(t, + `--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: some.deployment + namespace: some.namespace + labels: + label.one: value.one + label.two: value.two +spec: + replicas: 123 + selector: + matchLabels: + name: some.deployment + match.label.one: match.value.one + match.label.two: match.value.two + template: + metadata: + labels: + name: some.deployment + match.label.one: match.value.one + match.label.two: match.value.two + spec: + serviceAccountName: some.service.account + containers: + - env: + - name: an.env.var + value: a.value + image: an.image + name: a.container + resources: {} + - image: another.image + name: another.container + resources: {} + volumeMounts: + - mountPath: /config/map + name: config-map-volume + volumes: + - configMap: + items: + - key: config + path: config.yaml + name: some-config-map + name: config-map-volume +`, dep.Render(t)) +} diff --git a/tests/testutils/kubeutils/manifests/manifest.go b/tests/testutils/kubeutils/manifests/manifest.go index 78ff58d012..c2e3ba2743 100644 --- a/tests/testutils/kubeutils/manifests/manifest.go +++ b/tests/testutils/kubeutils/manifests/manifest.go @@ -18,12 +18,18 @@ package manifests import ( "bytes" "strings" + "testing" "text/template" "github.com/Masterminds/sprig/v3" + "github.com/stretchr/testify/require" "sigs.k8s.io/yaml" ) +type renderable interface { + Render(tb testing.TB) string +} + type M[T any] struct { template string } @@ -36,16 +42,21 @@ func Manifest[T any](template string) M[T] { // Render takes an instance of the type argument and renders the Manifest's // template w/ its fields. -func (m M[T]) Render(t T) (string, error) { +func (m M[T]) Render(t T, tb testing.TB) string { out := &bytes.Buffer{} tpl, err := template.New("").Funcs(funcMap()).Parse(m.template) - if err != nil { - return "", err - } - if err = tpl.Execute(out, t); err != nil { - return "", err + require.NoError(tb, err) + err = tpl.Execute(out, t) + require.NoError(tb, err) + return out.String() +} + +func RenderAll(tb testing.TB, manifests ...renderable) string { + var rendered []string + for _, m := range manifests { + rendered = append(rendered, m.Render(tb)) } - return out.String(), nil + return strings.Join(rendered, "") } // funcMap provides all sprig functions with an additional k8s yaml helper. diff --git a/tests/testutils/kubeutils/manifests/manifest_test.go b/tests/testutils/kubeutils/manifests/manifest_test.go index 9fbadc6d97..95583286ce 100644 --- a/tests/testutils/kubeutils/manifests/manifest_test.go +++ b/tests/testutils/kubeutils/manifests/manifest_test.go @@ -24,23 +24,46 @@ import ( corev1 "k8s.io/api/core/v1" ) -func TestManifest(t *testing.T) { - type One struct { - Thing string - AnotherThing string - } +type one struct { + Thing string + AnotherThing string +} + +func (o one) Render(tb testing.TB) string { + tmplt := `--- +thing: "{{.Thing}}" +anotherThing: "{{.AnotherThing}}" +` + man := Manifest[one](tmplt) + return man.Render(o, tb) +} - man := Manifest[One]("{{.Thing}}") - manifest, err := man.Render(One{Thing: "thing"}) - require.NoError(t, err) +func TestManifest(t *testing.T) { + man := Manifest[one]("{{.Thing}}") + manifest := man.Render(one{Thing: "thing"}, t) require.Equal(t, "thing", manifest) - man = Manifest[One]("{{ .AnotherThing | upper }}") - manifest, err = man.Render(One{AnotherThing: "another.thing"}) - require.NoError(t, err) + man = Manifest[one]("{{ .AnotherThing | upper }}") + manifest = man.Render(one{AnotherThing: "another.thing"}, t) require.Equal(t, "ANOTHER.THING", manifest) } +func TestRenderAll(t *testing.T) { + first := one{} + second := one{Thing: "some", AnotherThing: "thing"} + third := one{AnotherThing: "another.thing"} + require.Equal(t, `--- +thing: "" +anotherThing: "" +--- +thing: "some" +anotherThing: "thing" +--- +thing: "" +anotherThing: "another.thing" +`, RenderAll(t, first, second, third)) +} + func TestK8sYaml(t *testing.T) { type Thing struct { Container corev1.Container @@ -49,15 +72,14 @@ func TestK8sYaml(t *testing.T) { man := Manifest[Thing](`container: {{ .Container | toYaml | indent 2 }} `) - manifest, err := man.Render(Thing{Container: corev1.Container{ + manifest := man.Render(Thing{Container: corev1.Container{ Name: "container-name", Image: "container-image", Command: []string{"container", "command"}, Args: []string{"arg.one", "arg.two"}, WorkingDir: "/working/dir", Ports: []corev1.ContainerPort{{Name: "a.port", HostPort: 123, ContainerPort: 234, Protocol: corev1.ProtocolUDP, HostIP: "1.2.3.4"}}, - }}) - require.NoError(t, err) + }}, t) require.Equal(t, `container: args: - arg.one diff --git a/tests/testutils/kubeutils/manifests/namespace.go b/tests/testutils/kubeutils/manifests/namespace.go new file mode 100644 index 0000000000..ebc18e52e3 --- /dev/null +++ b/tests/testutils/kubeutils/manifests/namespace.go @@ -0,0 +1,42 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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 manifests + +import "testing" + +type Namespace struct { + Labels map[string]string + Name string +} + +const namespaceTemplate = `--- +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Name }} +{{- if .Labels }} + labels: + {{- range $key, $value := .Labels }} + {{ $key }}: {{ $value }} + {{- end }} +{{- end }} +` + +var nm = Manifest[Namespace](namespaceTemplate) + +func (n Namespace) Render(t testing.TB) string { + return nm.Render(n, t) +} diff --git a/tests/testutils/kubeutils/manifests/namespace_test.go b/tests/testutils/kubeutils/manifests/namespace_test.go new file mode 100644 index 0000000000..cb19c8dc7d --- /dev/null +++ b/tests/testutils/kubeutils/manifests/namespace_test.go @@ -0,0 +1,59 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build testutils + +package manifests + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestNamespace(t *testing.T) { + ns := Namespace{ + Name: "some.namespace", + } + + require.Equal(t, + `--- +apiVersion: v1 +kind: Namespace +metadata: + name: some.namespace +`, ns.Render(t)) +} + +func TestNamespaceWithLabels(t *testing.T) { + ns := Namespace{ + Name: "some.namespace", + Labels: map[string]string{ + "label.one": "value.one", + "label.two": "value.two", + }, + } + + require.Equal(t, + `--- +apiVersion: v1 +kind: Namespace +metadata: + name: some.namespace + labels: + label.one: value.one + label.two: value.two +`, ns.Render(t)) +} diff --git a/tests/testutils/kubeutils/manifests/service.go b/tests/testutils/kubeutils/manifests/service.go new file mode 100644 index 0000000000..12d071cdb5 --- /dev/null +++ b/tests/testutils/kubeutils/manifests/service.go @@ -0,0 +1,55 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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 manifests + +import ( + "testing" + + corev1 "k8s.io/api/core/v1" +) + +// Service is a "k8s.io/api/core/v1.Service" convenience type +type Service struct { + Name string + Namespace string + Type corev1.ServiceType + Selector map[string]string + Ports []corev1.ServicePort +} + +const serviceTemplate = `--- +apiVersion: v1 +kind: Service +metadata: + name: {{ .Name }} + namespace: {{ .Namespace }} +spec: + type: {{ .Type }} + selector: + {{- range $key, $value := .Selector }} + {{ $key }}: {{ $value }} + {{- end }} +{{- if .Ports }} + ports: +{{ .Ports | toYaml | indent 4 }} +{{- end }} +` + +var sm = Manifest[Service](serviceTemplate) + +func (s Service) Render(t testing.TB) string { + return sm.Render(s, t) +} diff --git a/tests/testutils/kubeutils/manifests/service_test.go b/tests/testutils/kubeutils/manifests/service_test.go new file mode 100644 index 0000000000..e6613589aa --- /dev/null +++ b/tests/testutils/kubeutils/manifests/service_test.go @@ -0,0 +1,73 @@ +// Copyright Splunk, Inc. +// Copyright The OpenTelemetry Authors +// +// 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. + +//go:build testutils + +package manifests + +import ( + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" +) + +func TestService(t *testing.T) { + s := Service{ + Name: "some.service", + Namespace: "some.namespace", + Type: corev1.ServiceTypeLoadBalancer, + Selector: map[string]string{ + "selector.key": "selector.value", + }, + Ports: []corev1.ServicePort{ + { + Name: "port-one", + Protocol: corev1.ProtocolTCP, + Port: 12345, + TargetPort: intstr.FromInt32(23456), + }, + { + Name: "port-one", + Protocol: corev1.ProtocolTCP, + Port: 12345, + TargetPort: intstr.FromInt32(23456), + }, + }, + } + + require.Equal(t, + `--- +apiVersion: v1 +kind: Service +metadata: + name: some.service + namespace: some.namespace +spec: + type: LoadBalancer + selector: + selector.key: selector.value + ports: + - name: port-one + port: 12345 + protocol: TCP + targetPort: 23456 + - name: port-one + port: 12345 + protocol: TCP + targetPort: 23456 +`, s.Render(t)) +}