Skip to content

Commit

Permalink
test: add integration test for extraExporters
Browse files Browse the repository at this point in the history
Signed-off-by: Dominik Rosiek <[email protected]>
  • Loading branch information
Dominik Rosiek committed May 22, 2024
1 parent 421648a commit fd5ab33
Show file tree
Hide file tree
Showing 9 changed files with 699 additions and 1 deletion.
122 changes: 122 additions & 0 deletions tests/integration/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,128 @@ func GetLogsFeature() features.Feature {

}

func DeployAdditionalSumologicMock() features.Feature {
return features.New("create additional sumologic mock").
Setup(stepfuncs.KubectlApplyFOpt(internal.YamlPathAdditionalSumologicMock, internal.AdditionalSumologicMockNamespace)).
Feature()
}

func DeleteAdditionalSumologicMock() features.Feature {
return features.New("delete additional sumologic mock").
Setup(stepfuncs.KubectlDeleteFOpt(internal.YamlPathAdditionalSumologicMock, internal.AdditionalSumologicMockNamespace)).
Feature()
}

func GetAdditionalLogsFeature() features.Feature {
return features.New("additional exporter logs").
Assess("logs from log generator deployment present", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
logsGeneratorCount,
map[string]string{
"namespace": internal.LogsGeneratorName,
"pod_labels_app": internal.LogsGeneratorName,
"deployment": internal.LogsGeneratorName,
},
waitDuration,
tickDuration,
)).
Assess("logs from log generator daemonset present", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
logsGeneratorCount,
map[string]string{
"namespace": internal.LogsGeneratorName,
"pod_labels_app": internal.LogsGeneratorName,
"daemonset": internal.LogsGeneratorName,
},
waitDuration,
tickDuration,
)).
Assess("expected container log metadata is present for log generator deployment", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
logsGeneratorCount,
map[string]string{
"cluster": internal.ClusterName,
// TODO: uncomment this after v4 release
// or make it depend on the metadata provider
// "_collector": internal.ClusterName,
"namespace": internal.LogsGeneratorName,
"pod_labels_app": internal.LogsGeneratorName,
"container": internal.LogsGeneratorName,
"deployment": internal.LogsGeneratorName,
"pod": fmt.Sprintf("%s%s", internal.LogsGeneratorName, internal.PodDeploymentSuffixRegex),
"host": internal.NodeNameRegex,
"node": internal.NodeNameRegex,
"_sourceName": fmt.Sprintf(
"%s\\.%s%s\\.%s",
internal.LogsGeneratorNamespace,
internal.LogsGeneratorName,
internal.PodDeploymentSuffixRegex,
internal.LogsGeneratorName,
),
"_sourceCategory": fmt.Sprintf(
"%s/%s/%s", // dashes instead of hyphens due to sourceCategoryReplaceDash
internal.ClusterName,
strings.ReplaceAll(internal.LogsGeneratorNamespace, "-", "/"),
strings.ReplaceAll(internal.LogsGeneratorName, "-", "/"), // this is the pod name prefix, in this case the deployment name
),
"_sourceHost": internal.EmptyRegex,
},
waitDuration,
tickDuration,
)).
Assess("expected container log metadata is present for log generator daemonset", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
logsGeneratorCount,
map[string]string{
// TODO: uncomment this after v4 release
// or make it depend on the metadata provider
// "_collector": "kubernetes",
"namespace": internal.LogsGeneratorName,
"pod_labels_app": internal.LogsGeneratorName,
"container": internal.LogsGeneratorName,
"daemonset": internal.LogsGeneratorName,
"pod": fmt.Sprintf("%s%s", internal.LogsGeneratorName, internal.PodDaemonSetSuffixRegex),
"host": internal.NodeNameRegex,
"node": internal.NodeNameRegex,
"_sourceName": fmt.Sprintf(
"%s\\.%s%s\\.%s",
internal.LogsGeneratorNamespace,
internal.LogsGeneratorName,
internal.PodDaemonSetSuffixRegex,
internal.LogsGeneratorName,
),
"_sourceCategory": fmt.Sprintf(
"%s/%s/%s", // dashes instead of hyphens due to sourceCategoryReplaceDash
internal.ClusterName,
strings.ReplaceAll(internal.LogsGeneratorNamespace, "-", "/"),
strings.ReplaceAll(internal.LogsGeneratorName, "-", "/"), // this is the pod name prefix, in this case the DaemonSet name
),
"_sourceHost": internal.EmptyRegex,
},
waitDuration,
tickDuration,
)).
Assess("logs from node systemd present", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
10, // we don't really control this, just want to check if the logs show up
map[string]string{
"cluster": "kubernetes",
"_sourceName": internal.NotUndefinedRegex,
"_sourceCategory": "kubernetes/system",
"_sourceHost": internal.NodeNameRegex,
},
waitDuration,
tickDuration,
)).
Assess("logs from kubelet present", stepfuncs.WaitUntilExpectedAdditionalLogsPresent(
1, // we don't really control this, just want to check if the logs show up
map[string]string{
"cluster": "kubernetes",
"_sourceName": "k8s_kubelet",
"_sourceCategory": "kubernetes/kubelet",
"_sourceHost": internal.NodeNameRegex,
},
waitDuration,
tickDuration,
)).
Feature()
}

func GetMultilineLogsFeature() features.Feature {
return features.New("multiline logs").
Setup(stepfuncs.KubectlApplyFOpt(internal.MultilineLogsGenerator, internal.MultilineLogsNamespace)).
Expand Down
27 changes: 27 additions & 0 deletions tests/integration/helm_ot_routing_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
//go:build allversions
// +build allversions

package integration

import (
"testing"
)

func Test_Helm_Routing_OT(t *testing.T) {

installChecks := []featureCheck{
CheckSumologicSecret(15),
CheckOtelcolMetadataLogsInstall,
CheckOtelcolLogsCollectorInstall,
}

featInstall := GetInstallFeature(installChecks)

featLogs := GetLogsFeature()
featAdditionalLogs := GetAdditionalLogsFeature()

featDeployMock := DeployAdditionalSumologicMock()
featDeleteMock := DeleteAdditionalSumologicMock()

testenv.Test(t, featDeployMock, featInstall, featLogs, featAdditionalLogs, featDeleteMock)
}
4 changes: 4 additions & 0 deletions tests/integration/internal/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ const (
SumologicMockServicePort = 3000
SumologicMockServiceName = "sumologic-mock"

YamlPathAdditionalSumologicMock = "yamls/additional-sumologic-mock.yaml"
AdditionalSumologicMockServiceName = "sumologic-mock"
AdditionalSumologicMockNamespace = "additional-sumologic-mock"

LogsGeneratorNamespace = "logs-generator"
LogsGeneratorName = "logs-generator"
LogsGeneratorImage = "sumologic/kubernetes-tools:2.22.0"
Expand Down
8 changes: 8 additions & 0 deletions tests/integration/internal/k8s/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,14 @@ func WaitUntilSumologicMockAvailable(
waitDuration time.Duration,
tickDuration time.Duration,
) {
if ctxopts.Namespace(ctx) == internal.AdditionalSumologicMockNamespace {
kubectlOpts := *ctxopts.KubectlOptions(ctx)
kubectlOpts.Namespace = internal.AdditionalSumologicMockNamespace

k8s.WaitUntilServiceAvailable(t, &kubectlOpts, internal.AdditionalSumologicMockServiceName, int(waitDuration), tickDuration)
return
}

k8s.WaitUntilServiceAvailable(t, ctxopts.KubectlOptions(ctx), fmt.Sprintf("%s-%s", ctxopts.HelmRelease(ctx), internal.SumologicMockServiceName), int(waitDuration), tickDuration)
}

Expand Down
8 changes: 7 additions & 1 deletion tests/integration/internal/k8s/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@ func TunnelForSumologicMock(
kubectlOptions := *ctxopts.KubectlOptions(ctx)
kubectlOptions.Namespace = ctxopts.Namespace(ctx)

serviceName := fmt.Sprintf("%s-%s", ctxopts.HelmRelease(ctx), internal.SumologicMockServiceName)

if kubectlOptions.Namespace == internal.AdditionalSumologicMockNamespace {
serviceName = internal.AdditionalSumologicMockServiceName
}

tunnel := terrak8s.NewTunnel(
&kubectlOptions,
terrak8s.ResourceTypeService,
fmt.Sprintf("%s-%s", ctxopts.HelmRelease(ctx), internal.SumologicMockServiceName),
serviceName,
0,
internal.SumologicMockServicePort,
)
Expand Down
42 changes: 42 additions & 0 deletions tests/integration/internal/stepfuncs/assess_funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,48 @@ func WaitUntilExpectedLogsPresent(
}
}

// WaitUntilAdditionalLogsPresent returns a features.Func that can be used in `Assess` calls.
// It will wait until the provided number of logs with the provided labels are returned by additional sumologic-mock's HTTP API on
// the provided Service and port, until it succeeds or waitDuration passes.
func WaitUntilExpectedAdditionalLogsPresent(
expectedLogsCount uint,
expectedLogsMetadata map[string]string,
waitDuration time.Duration,
tickDuration time.Duration,
) features.Func {
return func(ctx context.Context, t *testing.T, envConf *envconf.Config) context.Context {
newCtx := ctxopts.WithNamespace(ctx, internal.AdditionalSumologicMockNamespace)
k8s_internal.WaitUntilSumologicMockAvailable(newCtx, t, waitDuration, tickDuration)

client, closeTunnelFunc := sumologicmock.NewClientWithK8sTunnel(newCtx, t)
defer closeTunnelFunc()

assert.Eventually(t, func() bool {
logsCount, err := client.GetLogsCount(t, expectedLogsMetadata)
if err != nil {
log.ErrorS(err, "failed getting log counts from sumologic-mock")
return false
}
if logsCount < expectedLogsCount {
log.InfoS(
"received logs, less than expected",
"received", logsCount,
"expected", expectedLogsCount,
)
return false
}
log.InfoS(
"received enough logs",
"received", logsCount,
"expected", expectedLogsCount,
"metadata", expectedLogsMetadata,
)
return true
}, waitDuration, tickDuration)
return ctx
}
}

// WaitUntilStatefulSetIsReady waits for a specified duration and check with the
// specified tick interval whether the stateful set (as described by the provided options)
// is ready.
Expand Down
Loading

0 comments on commit fd5ab33

Please sign in to comment.