From 3cb754e68d7bf4d2977c63f90b44382a34f7d24e Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 10 Apr 2026 15:12:26 -0700 Subject: [PATCH 01/26] add configmap processing test pipeline and test framework MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pipeline: azure-pipeline-config-tests.yaml (manual trigger) - Shared runner script: run-configtest-scenario.sh (apply → rollout restart → TestKube) - First test scenario: toggle collect_ama_logs_process_metrics, verify telegraf counts - Ginkgo DescribeTable with labeled entries for modular scenario addition - CountProcessInstances() utility function - TestKube CRS files for process-metrics-enabled and process-metrics-default --- .pipelines/azure-pipeline-config-tests.yaml | 141 ++++++++++++- ...s-agentconfig-process-metrics-enabled.yaml | 83 ++++++++ .../configprocessing_suite_test.go | 26 +++ .../configprocessing/configprocessing_test.go | 44 ++++ test/ginkgo-e2e/configprocessing/go.mod | 12 ++ test/ginkgo-e2e/configprocessing/go.sum | 194 ++++++++++++++++++ test/ginkgo-e2e/utils/constants.go | 4 + test/ginkgo-e2e/utils/kubernetes_api_utils.go | 22 ++ ...nfig-test-process-metrics-default-crs.yaml | 30 +++ ...nfig-test-process-metrics-enabled-crs.yaml | 30 +++ test/testkube/run-configtest-scenario.sh | 108 ++++++++++ 11 files changed, 690 insertions(+), 4 deletions(-) create mode 100644 test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml create mode 100644 test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go create mode 100644 test/ginkgo-e2e/configprocessing/configprocessing_test.go create mode 100644 test/ginkgo-e2e/configprocessing/go.mod create mode 100644 test/ginkgo-e2e/configprocessing/go.sum create mode 100644 test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml create mode 100644 test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml create mode 100644 test/testkube/run-configtest-scenario.sh diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 16a28ec71..715a0d2cb 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -1,4 +1,7 @@ -# ConfigMap Testing Pipeline for ama-logs (stub - full implementation in zane/configmap-testing-pipeline) +# ConfigMap Testing Pipeline for ama-logs +# Applies different ConfigMap variants, restarts pods, and runs scenario-specific Ginkgo tests via TestKube. +# Manual trigger only. + trigger: none pr: none @@ -9,13 +12,143 @@ parameters: - name: clusterResourceGroup displayName: 'AKS Cluster Resource Group' type: string + - name: branch + displayName: 'Git branch for TestKube workflows' + type: string + default: 'ci_prod' stages: - stage: ConfigMapTests jobs: - - job: Placeholder + - job: RunConfigMapTests + timeoutInMinutes: 120 + displayName: "ConfigMap Processing Tests" pool: name: Azure-Pipelines-CI-Test-EO + variables: + skipComponentGovernanceDetection: true steps: - - script: echo "Pipeline created. Point to branch zane/configmap-testing-pipeline for full implementation." - displayName: 'Placeholder' + - checkout: self + persistCredentials: true + + # === Setup === + + - script: | + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + displayName: 'Install Azure CLI' + + - script: | + set -euo pipefail + echo "Ensuring kubectl & helm are installed" + if ! command -v az >/dev/null 2>&1; then + echo "Azure CLI not found; aborting" >&2 + exit 1 + fi + if ! command -v kubectl >/dev/null 2>&1; then + echo "kubectl not found. Installing via 'az aks install-cli' with sudo" + sudo az aks install-cli + else + echo "kubectl already installed: $(kubectl version --client --short || true)" + fi + if ! command -v helm >/dev/null 2>&1; then + echo "Helm not found. Installing Helm 3" + curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash + else + echo "Helm already installed: $(helm version --short || true)" + fi + displayName: 'Install kubectl and Helm' + + - task: AzureCLI@2 + displayName: Get kubeconfig + inputs: + azureSubscription: 'ContainerInsights_Build_Subscription_CI' + scriptLocation: 'inlineScript' + scriptType: 'bash' + inlineScript: 'az aks get-credentials -g ${{ parameters.clusterResourceGroup }} -n ${{ parameters.clusterName }}' + + - script: | + echo "Install testkube CLI" + wget -qO - https://repo.testkube.io/key.pub | sudo apt-key add - + echo "deb https://repo.testkube.io/linux linux main" | sudo tee -a /etc/apt/sources.list + sudo apt-get update + sudo apt-get install -y testkube + displayName: 'Install Testkube CLI' + + - bash: | + set -euo pipefail + + # Remove stale CRDs that block Helm ownership + stale_crds=( + "testworkflowexecutions.testworkflows.testkube.io" + "testworkflows.testkube.io" + "testworkflows.testworkflows.testkube.io" + "testworkflowtemplates.testworkflows.testkube.io" + ) + echo "Checking for stale Testkube CRDs" + for crd in "${stale_crds[@]}"; do + if kubectl get crd "$crd" >/dev/null 2>&1; then + owner=$(kubectl get crd "$crd" -o jsonpath='{.metadata.labels.app\.kubernetes\.io/managed-by}') + if [[ "$owner" != "Helm" ]]; then + echo "Deleting CRD $crd with unmanaged owner: ${owner:-none}" + kubectl delete crd "$crd" --wait=true || true + fi + fi + done + + # Clean up existing TestKube installation if present + if helm list -n testkube 2>/dev/null | grep -q testkube; then + echo "Found existing Testkube installation. Cleaning up..." + helm uninstall testkube -n testkube || true + kubectl delete namespace testkube --wait=true --timeout=120s || true + sleep 30 + fi + + # Install TestKube + helm repo add kubeshop https://kubeshop.github.io/helm-charts + helm repo update + helm upgrade --install --create-namespace testkube kubeshop/testkube -n testkube -f ./helm-testkube-values.yaml + + # Apply RBAC + kubectl apply -f ./api-server-permissions.yaml + + echo "Waiting for TestKube to be ready..." + sleep 60 + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: 'Install TestKube on cluster' + + # === Scenario 1: process-metrics-enabled === + - bash: | + chmod +x ./run-configtest-scenario.sh + ./run-configtest-scenario.sh \ + --configmap "../../test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml" \ + --crs "./config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml" \ + --scenario "process-metrics-enabled" \ + --branch "${{ parameters.branch }}" + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: "ConfigTest: process-metrics-enabled" + continueOnError: true + + # === Scenario 2: process-metrics-default (restore defaults) === + - bash: | + chmod +x ./run-configtest-scenario.sh + ./run-configtest-scenario.sh \ + --configmap "../../kubernetes/container-azm-ms-agentconfig.yaml" \ + --crs "./config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml" \ + --scenario "process-metrics-default" \ + --branch "${{ parameters.branch }}" + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: "ConfigTest: process-metrics-default" + continueOnError: true + + # === Cleanup === + - bash: | + echo "Restoring original configmap..." + kubectl apply -f $(Build.SourcesDirectory)/kubernetes/container-azm-ms-agentconfig.yaml || true + + echo "Cleaning up Testkube installation..." + helm uninstall testkube -n testkube || true + kubectl delete namespace testkube --wait=true --timeout=120s || true + echo "Cleanup complete." + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: 'Cleanup' + condition: always() diff --git a/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml b/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml new file mode 100644 index 000000000..538ee8bbe --- /dev/null +++ b/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml @@ -0,0 +1,83 @@ +kind: ConfigMap +apiVersion: v1 +data: + schema-version: + #string.used by agent to parse config. supported versions are {v1}. Configs with other schema versions will be rejected by the agent. + v1 + config-version: + #string.used by customer to keep track of this config file's version in their source control/repository (max allowed 10 chars, other chars will be truncated) + ver1 + log-data-collection-settings: |- + # Log data collection settings + # Any errors related to config map settings can be found in the KubeMonAgentEvents table in the Log Analytics workspace that the cluster is sending data to. + + [log_collection_settings] + [log_collection_settings.stdout] + enabled = true + exclude_namespaces = ["kube-system","gatekeeper-system"] + + [log_collection_settings.stderr] + enabled = true + exclude_namespaces = ["kube-system","gatekeeper-system"] + + [log_collection_settings.env_var] + enabled = true + [log_collection_settings.enrich_container_logs] + enabled = false + [log_collection_settings.collect_all_kube_events] + enabled = false + [log_collection_settings.schema] + containerlog_schema_version = "v2" + + prometheus-data-collection-settings: |- + # Custom Prometheus metrics data collection settings + [prometheus_data_collection_settings.cluster] + interval = "1m" + monitor_kubernetes_pods = false + + [prometheus_data_collection_settings.node] + interval = "1m" + + metric_collection_settings: |- + # Metrics collection settings for metrics sent to Log Analytics and MDM + [metric_collection_settings.collect_kube_system_pv_metrics] + enabled = false + + alertable-metrics-configuration-settings: |- + # Alertable metrics configuration settings for container resource utilization + [alertable_metrics_configuration_settings.container_resource_utilization_thresholds] + container_cpu_threshold_percentage = 95.0 + container_memory_rss_threshold_percentage = 95.0 + container_memory_working_set_threshold_percentage = 95.0 + + # Alertable metrics configuration settings for persistent volume utilization + [alertable_metrics_configuration_settings.pv_utilization_thresholds] + pv_usage_threshold_percentage = 60.0 + + # Alertable metrics configuration settings for completed jobs count + [alertable_metrics_configuration_settings.job_completion_threshold] + job_completion_threshold_time_minutes = 360 + integrations: |- + [integrations.azure_network_policy_manager] + collect_basic_metrics = false + collect_advanced_metrics = false + [integrations.azure_subnet_ip_usage] + enabled = false + +# Doc - https://github.com/microsoft/Docker-Provider/blob/ci_prod/Documentation/AgentSettings/ReadMe.md + agent-settings: |- + [agent_settings.high_log_scale] + enabled = false + + [agent_settings.prometheus_fbit_settings] + tcp_listener_chunk_size = 10 + tcp_listener_buffer_size = 10 + tcp_listener_mem_buf_limit = 200 + + # Enable collection of ama-logs process metrics via telegraf + [agent_settings.collect_ama_logs_process_metrics] + enabled = true + +metadata: + name: container-azm-ms-agentconfig + namespace: kube-system diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go new file mode 100644 index 000000000..c71a7d139 --- /dev/null +++ b/test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go @@ -0,0 +1,26 @@ +package configprocessing_test + +import ( + "testing" + + "docker-provider/test/utils" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +var K8sClient *kubernetes.Clientset +var Cfg *rest.Config + +func TestConfigProcessing(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "ConfigMap Processing Test Suite") +} + +var _ = BeforeSuite(func() { + var err error + K8sClient, Cfg, err = utils.SetupKubernetesClient() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_test.go new file mode 100644 index 000000000..25101ca29 --- /dev/null +++ b/test/ginkgo-e2e/configprocessing/configprocessing_test.go @@ -0,0 +1,44 @@ +package configprocessing_test + +import ( + "docker-provider/test/utils" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +var _ = DescribeTable("Process count matches expected", + func(labelName, labelValue, containerName, processName string, expectedCount int) { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", labelName, labelValue, containerName, processName) + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedCount)) + }, + + // === Scenario: process-metrics-enabled === + Entry("ama-logs DS: 2 telegraf when process metrics enabled", + "component", "ama-logs-agent", "ama-logs", "telegraf", 2, + Label(utils.ConfigProcessMetricsEnabled)), + Entry("ama-logs-rs: 2 telegraf when process metrics enabled", + "rsName", "ama-logs-rs", "ama-logs", "telegraf", 2, + Label(utils.ConfigProcessMetricsEnabled)), + Entry("ama-logs-prometheus: 1 telegraf when process metrics enabled", + "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 1, + Label(utils.ConfigProcessMetricsEnabled)), + Entry("ama-logs-windows: 1 telegraf when process metrics enabled", + "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 1, + Label(utils.ConfigProcessMetricsEnabled)), + + // === Scenario: process-metrics-default === + Entry("ama-logs DS: 1 telegraf with default config", + "component", "ama-logs-agent", "ama-logs", "telegraf", 1, + Label(utils.ConfigProcessMetricsDefault)), + Entry("ama-logs-rs: 1 telegraf with default config", + "rsName", "ama-logs-rs", "ama-logs", "telegraf", 1, + Label(utils.ConfigProcessMetricsDefault)), + Entry("ama-logs-prometheus: 0 telegraf with default config", + "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 0, + Label(utils.ConfigProcessMetricsDefault)), + Entry("ama-logs-windows: 0 telegraf with default config", + "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 0, + Label(utils.ConfigProcessMetricsDefault)), +) diff --git a/test/ginkgo-e2e/configprocessing/go.mod b/test/ginkgo-e2e/configprocessing/go.mod new file mode 100644 index 000000000..dd46fee0b --- /dev/null +++ b/test/ginkgo-e2e/configprocessing/go.mod @@ -0,0 +1,12 @@ +module docker-provider/test/configprocessing + +go 1.26.1 + +replace docker-provider/test/utils => ../utils + +require ( + docker-provider/test/utils v0.0.0 + github.com/onsi/ginkgo/v2 v2.27.2 + github.com/onsi/gomega v1.38.2 + k8s.io/client-go v0.35.3 +) diff --git a/test/ginkgo-e2e/configprocessing/go.sum b/test/ginkgo-e2e/configprocessing/go.sum new file mode 100644 index 000000000..1a4d6f2c2 --- /dev/null +++ b/test/ginkgo-e2e/configprocessing/go.sum @@ -0,0 +1,194 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 h1:l+LIDHsZkFBiipIKhOn3m5/2MX4bwNwHYWyNulPaTis= +github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0/go.mod h1:BjVVBLUiZ/qR2a4PAhjs8uGXNfStD0tSxgxCMfcVRT8= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= +github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= +github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= +github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= +github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= +github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= +github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= +github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= +github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= +k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= +k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= +k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= +k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/test/ginkgo-e2e/utils/constants.go b/test/ginkgo-e2e/utils/constants.go index a5bb73f86..cf3922dea 100644 --- a/test/ginkgo-e2e/utils/constants.go +++ b/test/ginkgo-e2e/utils/constants.go @@ -24,4 +24,8 @@ const ( // IntermittentErrorThreshold is the maximum number of occurrences allowed for expected intermittent errors IntermittentErrorThreshold = 10 + + // ConfigMap processing test scenario labels + ConfigProcessMetricsEnabled = "config-processing-process-metrics-enabled" + ConfigProcessMetricsDefault = "config-processing-process-metrics-default" ) diff --git a/test/ginkgo-e2e/utils/kubernetes_api_utils.go b/test/ginkgo-e2e/utils/kubernetes_api_utils.go index ae795e989..f364652ba 100644 --- a/test/ginkgo-e2e/utils/kubernetes_api_utils.go +++ b/test/ginkgo-e2e/utils/kubernetes_api_utils.go @@ -548,6 +548,28 @@ func GetAllNodes(clientset *kubernetes.Clientset) ([]corev1.Node, error) { return nodes.Items, nil } +// CountProcessInstances counts instances of a process in the given container +// across pods matching the label. Returns the count from the first matching pod. +func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, + namespace, labelName, labelValue, containerName, processName string) (int, error) { + + pods, err := GetPodsWithLabel(client, namespace, labelName, labelValue) + if err != nil { + return 0, err + } + + command := []string{"bash", "-c", + fmt.Sprintf("ps aux | grep '%s' | grep -v grep | wc -l", processName)} + stdout, _, err := ExecCmd(client, config, pods[0].Name, containerName, namespace, command) + if err != nil { + return 0, err + } + + count := 0 + fmt.Sscanf(strings.TrimSpace(stdout), "%d", &count) + return count, nil +} + // CheckFileForErrors checks if a specific file in a linux container contains errors. // It tolerates intermittent errors up to 10 occurrences per pattern. func CheckFileForErrors(clientset *kubernetes.Clientset, Cfg *rest.Config, namespace, labelName, labelValue, containerName, filePath string) error { diff --git a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml b/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml new file mode 100644 index 000000000..5dd4b89bf --- /dev/null +++ b/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml @@ -0,0 +1,30 @@ +apiVersion: testworkflows.testkube.io/v1 +kind: TestWorkflow +metadata: + name: config-test-process-metrics-default + namespace: testkube +spec: + config: + GOTOOLCHAIN: + type: string + default: "" + content: + git: + uri: https://github.com/microsoft/Docker-Provider/ + revision: ci_prod + paths: + - test/ginkgo-e2e + steps: + - name: Run test + container: + workingDir: /data/repo/test/ginkgo-e2e + image: cerebro31/ginkgo-test:latest + env: + - name: GOTOOLCHAIN + value: "{{config.GOTOOLCHAIN}}" + shell: | + ginkgo run -r --label-filter "config-processing-process-metrics-default" ./configprocessing + pod: + nodeSelector: + kubernetes.io/os: linux + kubernetes.io/arch: amd64 diff --git a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml b/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml new file mode 100644 index 000000000..86ebcaf47 --- /dev/null +++ b/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml @@ -0,0 +1,30 @@ +apiVersion: testworkflows.testkube.io/v1 +kind: TestWorkflow +metadata: + name: config-test-process-metrics-enabled + namespace: testkube +spec: + config: + GOTOOLCHAIN: + type: string + default: "" + content: + git: + uri: https://github.com/microsoft/Docker-Provider/ + revision: ci_prod + paths: + - test/ginkgo-e2e + steps: + - name: Run test + container: + workingDir: /data/repo/test/ginkgo-e2e + image: cerebro31/ginkgo-test:latest + env: + - name: GOTOOLCHAIN + value: "{{config.GOTOOLCHAIN}}" + shell: | + ginkgo run -r --label-filter "config-processing-process-metrics-enabled" ./configprocessing + pod: + nodeSelector: + kubernetes.io/os: linux + kubernetes.io/arch: amd64 diff --git a/test/testkube/run-configtest-scenario.sh b/test/testkube/run-configtest-scenario.sh new file mode 100644 index 000000000..e8f32605d --- /dev/null +++ b/test/testkube/run-configtest-scenario.sh @@ -0,0 +1,108 @@ +#!/bin/bash +set -euo pipefail + +# Generic script for running a single configmap test scenario. +# Usage: +# ./run-configtest-scenario.sh \ +# --configmap \ +# --crs \ +# --scenario \ +# --branch +# +# Steps: +# 1. Apply the configmap variant +# 2. Rollout restart ama-logs workloads +# 3. Wait for rollout to complete +# 4. Apply the TestKube workflow CRD +# 5. Run the testworkflow and collect results + +CONFIGMAP="" +CRS="" +SCENARIO="" +BRANCH="ci_prod" + +while [[ $# -gt 0 ]]; do + case "$1" in + --configmap) CONFIGMAP="$2"; shift 2 ;; + --crs) CRS="$2"; shift 2 ;; + --scenario) SCENARIO="$2"; shift 2 ;; + --branch) BRANCH="$2"; shift 2 ;; + *) echo "Unknown argument: $1"; exit 1 ;; + esac +done + +if [[ -z "$CONFIGMAP" || -z "$CRS" || -z "$SCENARIO" ]]; then + echo "Error: --configmap, --crs, and --scenario are required" + exit 1 +fi + +WORKFLOW_NAME="config-test-${SCENARIO}" + +echo "========== ConfigTest Scenario: ${SCENARIO} ==========" + +# Step 1: Apply configmap variant +echo "Applying configmap: ${CONFIGMAP}" +kubectl apply -f "${CONFIGMAP}" + +# Step 2: Rollout restart ama-logs workloads +echo "Restarting ama-logs workloads..." +kubectl rollout restart ds/ama-logs -n kube-system +kubectl rollout restart deploy/ama-logs-rs -n kube-system +kubectl rollout restart ds/ama-logs-windows -n kube-system 2>/dev/null || echo "ama-logs-windows daemonset not found (may not exist on this cluster), skipping" + +# Step 3: Wait for rollout to complete +echo "Waiting for rollouts to complete..." +kubectl rollout status ds/ama-logs -n kube-system --timeout=5m +kubectl rollout status deploy/ama-logs-rs -n kube-system --timeout=5m +kubectl rollout status ds/ama-logs-windows -n kube-system --timeout=5m 2>/dev/null || echo "ama-logs-windows rollout status skipped" + +# Step 4: Apply the TestKube workflow CRD +echo "Applying TestKube workflow CRD: ${CRS}" +kubectl apply -f "${CRS}" + +# Step 5: Run the testworkflow +echo "Running testworkflow: ${WORKFLOW_NAME}" +kubectl testkube run testworkflow "${WORKFLOW_NAME}" \ + --config GOTOOLCHAIN="auto" \ + --verbose + +echo "Waiting for execution to be created..." +sleep 5 + +echo "Fetching testworkflow executions for ${WORKFLOW_NAME}..." +kubectl testkube get testworkflowexecution +execution_id=$(kubectl testkube get testworkflowexecution | grep -i "${WORKFLOW_NAME}" | head -n 1 | awk '{print $1}') + +echo "Execution ID: ${execution_id}" + +if [[ -z "${execution_id}" ]]; then + echo "Error: Could not find execution ID for ${WORKFLOW_NAME}" + exit 1 +fi + +# Watch until the testworkflow finishes +kubectl testkube watch testworkflowexecution "${execution_id}" + +# Get the results as a formatted JSON file +kubectl testkube get testworkflowexecution "${execution_id}" --output json > "testkube-results-${SCENARIO}.json" + +# Verify the JSON is valid +if ! jq empty "testkube-results-${SCENARIO}.json" 2>/dev/null; then + echo "Error: Failed to get valid JSON results for scenario ${SCENARIO}" + echo "Contents of testkube-results-${SCENARIO}.json:" + cat "testkube-results-${SCENARIO}.json" + exit 1 +fi + +# Check result status +result_status=$(jq -r '.result.status' "testkube-results-${SCENARIO}.json") +if [[ "${result_status}" == "failed" ]]; then + echo "TestWorkflow FAILED for scenario: ${SCENARIO} (execution: ${execution_id})" + kubectl testkube get testworkflowexecution "${execution_id}" --logs-only > "execution-${SCENARIO}.log" 2>&1 + cat "execution-${SCENARIO}.log" + exit 1 +else + echo "TestWorkflow PASSED for scenario: ${SCENARIO} (execution: ${execution_id})" +fi + +echo "========== Scenario ${SCENARIO} complete ==========" From 2db2e96f2807115932cb5502d2bb208b6351733d Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 10 Apr 2026 22:43:15 -0700 Subject: [PATCH 02/26] fix: patch CRS revision with --branch parameter TestKube clones the repo at the revision specified in the CRS. The configprocessing tests don't exist on ci_prod yet, so the script now patches the CRS revision before applying it. --- test/testkube/run-configtest-scenario.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/test/testkube/run-configtest-scenario.sh b/test/testkube/run-configtest-scenario.sh index e8f32605d..54e1f906f 100644 --- a/test/testkube/run-configtest-scenario.sh +++ b/test/testkube/run-configtest-scenario.sh @@ -56,9 +56,11 @@ kubectl rollout status ds/ama-logs -n kube-system --timeout=5m kubectl rollout status deploy/ama-logs-rs -n kube-system --timeout=5m kubectl rollout status ds/ama-logs-windows -n kube-system --timeout=5m 2>/dev/null || echo "ama-logs-windows rollout status skipped" -# Step 4: Apply the TestKube workflow CRD -echo "Applying TestKube workflow CRD: ${CRS}" -kubectl apply -f "${CRS}" +# Step 4: Apply the TestKube workflow CRD (with branch override) +echo "Applying TestKube workflow CRD: ${CRS} (branch: ${BRANCH})" +CRS_PATCHED="${CRS%.yaml}-patched.yaml" +sed "s|revision: ci_prod|revision: ${BRANCH}|g" "${CRS}" > "${CRS_PATCHED}" +kubectl apply -f "${CRS_PATCHED}" # Step 5: Run the testworkflow echo "Running testworkflow: ${WORKFLOW_NAME}" From 7e2b2d5ff0a01109deb124b69706906d789df5e6 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 10 Apr 2026 22:54:46 -0700 Subject: [PATCH 03/26] fix: configmap variant should be exact copy of base plus only the changed setting --- ...s-agentconfig-process-metrics-enabled.yaml | 187 +++++++++++++++++- 1 file changed, 186 insertions(+), 1 deletion(-) diff --git a/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml b/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml index 538ee8bbe..ff30b4547 100644 --- a/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml +++ b/test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml @@ -12,50 +12,155 @@ data: # Any errors related to config map settings can be found in the KubeMonAgentEvents table in the Log Analytics workspace that the cluster is sending data to. [log_collection_settings] + [log_collection_settings.multi_tenancy] + enabled = false # High log scale MUST be enabled to use this feature. Refer to https://aka.ms/cihsmode for more details on high log scale mode + disable_fallback_ingestion = false # If enabled, logs of the k8s namespaces for which ContainerLogV2Extension DCR is not configured will not be ingested to the default DCR. + [log_collection_settings.stdout] + # In the absense of this configmap, default value for enabled is true enabled = true + # exclude_namespaces setting holds good only if enabled is set to true + # kube-system,gatekeeper-system log collection are disabled by default in the absence of 'log_collection_settings.stdout' setting. If you want to enable kube-system,gatekeeper-system, remove them from the following setting. + # If you want to continue to disable kube-system,gatekeeper-system log collection keep the namespaces in the following setting and add any other namespace you want to disable log collection to the array. + # In the absense of this configmap, default value for exclude_namespaces = ["kube-system","gatekeeper-system"] exclude_namespaces = ["kube-system","gatekeeper-system"] + # If you want to collect logs from only selective pods inside system namespaces add them to the following setting. Provide namepace:controllerName of the system pod. NOTE: this setting is only for pods in system namespaces + # Valid values for system namespaces are: kube-system, azure-arc, gatekeeper-system, kube-public, kube-node-lease, calico-system. The system namespace used should not be present in exclude_namespaces + # collect_system_pod_logs = ["kube-system:coredns"] [log_collection_settings.stderr] + # Default value for enabled is true enabled = true + # exclude_namespaces setting holds good only if enabled is set to true + # kube-system,gatekeeper-system log collection are disabled by default in the absence of 'log_collection_settings.stderr' setting. If you want to enable kube-system,gatekeeper-system, remove them from the following setting. + # If you want to continue to disable kube-system,gatekeeper-system log collection keep the namespaces in the following setting and add any other namespace you want to disable log collection to the array. + # In the absense of this configmap, default value for exclude_namespaces = ["kube-system","gatekeeper-system"] exclude_namespaces = ["kube-system","gatekeeper-system"] + # If you want to collect logs from only selective pods inside system namespaces add them to the following setting. Provide namepace:controllerName of the system pod. NOTE: this setting is only for pods in system namespaces + # Valid values for system namespaces are: kube-system, azure-arc, gatekeeper-system, kube-public, kube-node-lease, calico-system. The system namespace used should not be present in exclude_namespaces + # collect_system_pod_logs = ["kube-system:coredns"] [log_collection_settings.env_var] + # In the absense of this configmap, default value for enabled is true enabled = true [log_collection_settings.enrich_container_logs] + # In the absense of this configmap, default value for enrich_container_logs is false enabled = false + # When this is enabled (enabled = true), every container log entry (both stdout & stderr) will be enriched with container Name & container Image [log_collection_settings.collect_all_kube_events] + # In the absense of this configmap, default value for collect_all_kube_events is false + # When the setting is set to false, only the kube events with !normal event type will be collected enabled = false + # When this is enabled (enabled = true), all kube events including normal events will be collected [log_collection_settings.schema] + # In the absence of this configmap, default value for containerlog_schema_version is "v1" if "v2" is not enabled while onboarding + # Supported values for this setting are "v1","v2" + # See documentation at https://aka.ms/ContainerLogv2 for benefits of v2 schema over v1 schema containerlog_schema_version = "v2" + #[log_collection_settings.enable_multiline_logs] + # fluent-bit based multiline log collection for .NET, Go, Java, and Python stacktraces. Update stacktrace_languages to specificy which languages to collect stacktraces for(valid inputs: "go", "java", "python", "dotnet"). + # NOTE: for better performance consider enabling only for languages that are needed. Dotnet is experimental and may not work in all cases. + # If enabled will also stitch together container logs split by docker/cri due to size limits(16KB per log line) up to 64 KB. + # Requires ContainerLogV2 schema to be enabled. See https://aka.ms/ContainerLogv2 for more details. + # enabled = "false" + # stacktrace_languages = [] + #[log_collection_settings.metadata_collection] + # kube_meta_cache_ttl_secs is a configurable option for K8s cached metadata. Default is 60s. You may adjust it in below section [agent_settings.k8s_metadata_config]. Reference link: https://docs.fluentbit.io/manual/pipeline/filters/kubernetes#configuration-parameters + # if enabled will collect kubernetes metadata for ContainerLogv2 schema. Default is false. + # enabled = false + # if include_fields commented out or empty, all fields will be included. If include_fields is set, only the fields listed will be included. + # include_fields = ["podLabels","podAnnotations","podUid","image","imageID","imageRepo","imageTag"] + #[log_collection_settings.filter_using_annotations] + # if enabled will exclude logs from pods with annotations fluentbit.io/exclude: "true". + # Read more: https://docs.fluentbit.io/manual/pipeline/filters/kubernetes#kubernetes-annotations + # enabled = false prometheus-data-collection-settings: |- # Custom Prometheus metrics data collection settings [prometheus_data_collection_settings.cluster] + # Cluster level scrape endpoint(s). These metrics will be scraped from agent's Replicaset (singleton) + # Any errors related to prometheus scraping can be found in the KubeMonAgentEvents table in the Log Analytics workspace that the cluster is sending data to. + + #Interval specifying how often to scrape for metrics. This is duration of time and can be specified for supporting settings by combining an integer value and time unit as a string value. Valid time units are ns, us (or µs), ms, s, m, h. interval = "1m" + + ## Uncomment the following settings with valid string arrays for prometheus scraping + #fieldpass = ["metric_to_pass1", "metric_to_pass12"] + + #fielddrop = ["metric_to_drop"] + + # An array of urls to scrape metrics from. + # urls = ["http://myurl:9101/metrics"] + + # An array of Kubernetes services to scrape metrics from. + # kubernetes_services = ["http://my-service-dns.my-namespace:9102/metrics"] + + # When monitor_kubernetes_pods = true, prometheus sidecar container will scrape Kubernetes pods for the following prometheus annotations: + # - prometheus.io/scrape: Enable scraping for this pod + # - prometheus.io/scheme: Default is http + # - prometheus.io/path: If the metrics path is not /metrics, define it with this annotation. + # - prometheus.io/port: If port is not 9102 use this annotation monitor_kubernetes_pods = false + ## Restricts Kubernetes monitoring to namespaces for pods that have annotations set and are scraped using the monitor_kubernetes_pods setting. + ## This will take effect when monitor_kubernetes_pods is set to true + ## ex: monitor_kubernetes_pods_namespaces = ["default1", "default2", "default3"] + # monitor_kubernetes_pods_namespaces = ["default1"] + + ## Label selector to target pods which have the specified label + ## This will take effect when monitor_kubernetes_pods is set to true + ## Reference the docs at https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors + # kubernetes_label_selector = "env=dev,app=nginx" + + ## Field selector to target pods which have the specified field + ## This will take effect when monitor_kubernetes_pods is set to true + ## Reference the docs at https://kubernetes.io/docs/concepts/overview/working-with-objects/field-selectors/ + ## eg. To scrape pods on a specific node + # kubernetes_field_selector = "spec.nodeName=$HOSTNAME" + [prometheus_data_collection_settings.node] + # Node level scrape endpoint(s). These metrics will be scraped from agent's DaemonSet running in every node in the cluster + # Any errors related to prometheus scraping can be found in the KubeMonAgentEvents table in the Log Analytics workspace that the cluster is sending data to. + + #Interval specifying how often to scrape for metrics. This is duration of time and can be specified for supporting settings by combining an integer value and time unit as a string value. Valid time units are ns, us (or µs), ms, s, m, h. interval = "1m" + ## Uncomment the following settings with valid string arrays for prometheus scraping + + # An array of urls to scrape metrics from. $NODE_IP (all upper case) will substitute of running Node's IP address + # urls = ["http://$NODE_IP:9103/metrics"] + + #fieldpass = ["metric_to_pass1", "metric_to_pass12"] + + #fielddrop = ["metric_to_drop"] + metric_collection_settings: |- # Metrics collection settings for metrics sent to Log Analytics and MDM [metric_collection_settings.collect_kube_system_pv_metrics] + # In the absense of this configmap, default value for collect_kube_system_pv_metrics is false + # When the setting is set to false, only the persistent volume metrics outside the kube-system namespace will be collected enabled = false + # When this is enabled (enabled = true), persistent volume metrics including those in the kube-system namespace will be collected alertable-metrics-configuration-settings: |- # Alertable metrics configuration settings for container resource utilization [alertable_metrics_configuration_settings.container_resource_utilization_thresholds] + # The threshold(Type Float) will be rounded off to 2 decimal points + # Threshold for container cpu, metric will be sent only when cpu utilization exceeds or becomes equal to the following percentage container_cpu_threshold_percentage = 95.0 + # Threshold for container memoryRss, metric will be sent only when memory rss exceeds or becomes equal to the following percentage container_memory_rss_threshold_percentage = 95.0 + # Threshold for container memoryWorkingSet, metric will be sent only when memory working set exceeds or becomes equal to the following percentage container_memory_working_set_threshold_percentage = 95.0 # Alertable metrics configuration settings for persistent volume utilization [alertable_metrics_configuration_settings.pv_utilization_thresholds] + # Threshold for persistent volume usage bytes, metric will be sent only when persistent volume utilization exceeds or becomes equal to the following percentage pv_usage_threshold_percentage = 60.0 # Alertable metrics configuration settings for completed jobs count [alertable_metrics_configuration_settings.job_completion_threshold] + # Threshold for completed job count , metric will be sent only for those jobs which were completed earlier than the following threshold job_completion_threshold_time_minutes = 360 integrations: |- [integrations.azure_network_policy_manager] @@ -66,15 +171,95 @@ data: # Doc - https://github.com/microsoft/Docker-Provider/blob/ci_prod/Documentation/AgentSettings/ReadMe.md agent-settings: |- + # High log scale option for container logs high log volume scenarios. This mode is optimized for high log volume scenarios and have little higher resource utilization on low scale which will be addressed in subsequent agent releases. + # Refer to public documentation for more details - https://aka.ms/cihsmode before enabling this setting as this setting has additional dependencies such as Data Collection endpoint and Microsoft-ContainerLogV2-HighScale stream instead of Microsoft-ContainerLogV2. [agent_settings.high_log_scale] enabled = false + # Retina Network Flow Logs throttle settings + # Controls the rate at which network flow log messages are processed. + # [agent_settings.networkflow_logs_config] + # throttle_enabled = true # By default is true and adjust this to control whether to enable or disable network flow log messages. + # throttle_rate = 5000 # By default is 5000 and range from 1 to 25,000 and adjust this to control the amount of messages for the time. + # throttle_window = 300 # By default is 300 and adjust this to control the amount of intervals to calculate average over. + # throttle_interval = "1s" # By default is 1s and adjust this to control time interval, expressed in "sleep" format. e.g 3s, 1.5m, 0.5h etc.. + # throttle_print = false # By default is false and adjust this to control whether to print status messages with current rate and the limits to information logs. + + # prometheus scrape fluent bit settings for high scale + # buffer size should be greater than or equal to chunk size else we set it to chunk size. + # settings scoped to prometheus sidecar container. all values in mb [agent_settings.prometheus_fbit_settings] tcp_listener_chunk_size = 10 tcp_listener_buffer_size = 10 tcp_listener_mem_buf_limit = 200 - # Enable collection of ama-logs process metrics via telegraf + # prometheus scrape fluent bit settings for high scale + # buffer size should be greater than or equal to chunk size else we set it to chunk size. + # settings scoped to daemonset container. all values in mb + # [agent_settings.node_prometheus_fbit_settings] + # tcp_listener_chunk_size = 1 + # tcp_listener_buffer_size = 1 + # tcp_listener_mem_buf_limit = 10 + + # prometheus scrape fluent bit settings for high scale + # buffer size should be greater than or equal to chunk size else we set it to chunk size. + # settings scoped to replicaset container. all values in mb + # [agent_settings.cluster_prometheus_fbit_settings] + # tcp_listener_chunk_size = 1 + # tcp_listener_buffer_size = 1 + # tcp_listener_mem_buf_limit = 10 + + # The following settings are "undocumented", we don't recommend uncommenting them unless directed by Microsoft. + # They increase the maximum stdout/stderr log collection rate but will also cause higher cpu/memory usage. + ## Ref for more details about Ignore_Older - https://docs.fluentbit.io/manual/v/1.7/pipeline/inputs/tail + # [agent_settings.fbit_config] + # log_flush_interval_secs = "1" # default value is 15 + # tail_mem_buf_limit_megabytes = "10" # default value is 10 + # tail_buf_chunksize_megabytes = "1" # default value is 32kb (comment out this line for default) + # tail_buf_maxsize_megabytes = "1" # default value is 32kb (comment out this line for default) + # enable_internal_metrics = "true" # default value is false + # tail_ignore_older = "5m" # default value same as fluent-bit default i.e.0m + + # On both AKS & Arc K8s enviornments, if Cluster has configured with Forward Proxy then Proxy settings automatically applied and used for the agent + # Certain configurations, proxy config should be ignored for example Cluster with AMPLS + Proxy + # in such scenarios, use the following config to ignore proxy settings + # [agent_settings.proxy_config] + # ignore_proxy_settings = "true" # if this is not applied, default value is false + + # Disables fluent-bit for perf and container inventory for Windows + #[agent_settings.windows_fluent_bit] + # disabled = "true" + + # The following settings are "undocumented", we don't recommend uncommenting them unless directed by Microsoft. + # Configuration settings for the waittime for the network listeners to be available + # [agent_settings.network_listener_waittime] + # tcp_port_25226 = 45 # Port 25226 is used for telegraf to fluent-bit data in ReplicaSet + # tcp_port_25228 = 60 # Port 25228 is used for telegraf to fluentd data + # tcp_port_25229 = 45 # Port 25229 is used for telegraf to fluent-bit data in DaemonSet + + # The following settings are "undocumented", we don't recommend uncommenting them unless directed by Microsoft. + # [agent_settings.mdsd_config] + # monitoring_max_event_rate = "50000" # default 20K eps + # backpressure_memory_threshold_in_mb = "1500" # default 3500MB + # upload_max_size_in_mb = "20" # default 2MB + # upload_frequency_seconds = "1" # default 60 upload_frequency_seconds + # compression_level = "0" # supported levels 0 to 9 and 0 means no compression + + # Disables fluentd and uses fluent-bit for all data collection + # [agent_settings.resource_optimization] + # enabled = false # if this is not applied, default value is false + + # The following settings are "undocumented", we don't recommend uncommenting them unless directed by Microsoft. + # [agent_settings.telemetry_config] + # disable_telemetry = false # if this is not applied, default value is false + + # The following setting is for KubernetesMetadata CacheTTL Settings. + # [agent_settings.k8s_metadata_config] + # kube_meta_cache_ttl_secs = 60 # if this is not applied, default value is 60s + + # [agent_settings.chunk_config] + # PODS_CHUNK_SIZE = 10 # default value is 1000 and for large clusters with high number of pods, this can reduced to smaller value if the gaps in KubePodInventory/KubeNodeInventory data. + [agent_settings.collect_ama_logs_process_metrics] enabled = true From 5d7eff86a1ec4534fb2d3a3c365f8beb854bacd9 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 10 Apr 2026 23:06:50 -0700 Subject: [PATCH 04/26] fix: use PowerShell for Windows container process counting CountProcessInstances uses bash which doesn't exist in Windows containers. Added CountWindowsProcessInstances using PowerShell's Get-Process, and split the test table so Windows entries use the correct function. --- .../configprocessing/configprocessing_test.go | 22 +++++++++++++--- test/ginkgo-e2e/utils/kubernetes_api_utils.go | 26 +++++++++++++++++-- 2 files changed, 42 insertions(+), 6 deletions(-) diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_test.go index 25101ca29..eab2a29aa 100644 --- a/test/ginkgo-e2e/configprocessing/configprocessing_test.go +++ b/test/ginkgo-e2e/configprocessing/configprocessing_test.go @@ -7,7 +7,8 @@ import ( . "github.com/onsi/gomega" ) -var _ = DescribeTable("Process count matches expected", +// Linux container process count checks +var _ = DescribeTable("Linux process count matches expected", func(labelName, labelValue, containerName, processName string, expectedCount int) { count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", labelName, labelValue, containerName, processName) Expect(err).NotTo(HaveOccurred()) @@ -24,9 +25,6 @@ var _ = DescribeTable("Process count matches expected", Entry("ama-logs-prometheus: 1 telegraf when process metrics enabled", "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 1, Label(utils.ConfigProcessMetricsEnabled)), - Entry("ama-logs-windows: 1 telegraf when process metrics enabled", - "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 1, - Label(utils.ConfigProcessMetricsEnabled)), // === Scenario: process-metrics-default === Entry("ama-logs DS: 1 telegraf with default config", @@ -38,6 +36,22 @@ var _ = DescribeTable("Process count matches expected", Entry("ama-logs-prometheus: 0 telegraf with default config", "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 0, Label(utils.ConfigProcessMetricsDefault)), +) + +// Windows container process count checks (uses PowerShell instead of bash) +var _ = DescribeTable("Windows process count matches expected", + func(labelName, labelValue, containerName, processName string, expectedCount int) { + count, err := utils.CountWindowsProcessInstances(K8sClient, Cfg, "kube-system", labelName, labelValue, containerName, processName) + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedCount)) + }, + + // === Scenario: process-metrics-enabled === + Entry("ama-logs-windows: 1 telegraf when process metrics enabled", + "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 1, + Label(utils.ConfigProcessMetricsEnabled)), + + // === Scenario: process-metrics-default === Entry("ama-logs-windows: 0 telegraf with default config", "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 0, Label(utils.ConfigProcessMetricsDefault)), diff --git a/test/ginkgo-e2e/utils/kubernetes_api_utils.go b/test/ginkgo-e2e/utils/kubernetes_api_utils.go index f364652ba..999365aa2 100644 --- a/test/ginkgo-e2e/utils/kubernetes_api_utils.go +++ b/test/ginkgo-e2e/utils/kubernetes_api_utils.go @@ -548,8 +548,8 @@ func GetAllNodes(clientset *kubernetes.Clientset) ([]corev1.Node, error) { return nodes.Items, nil } -// CountProcessInstances counts instances of a process in the given container -// across pods matching the label. Returns the count from the first matching pod. +// CountProcessInstances counts instances of a process in a Linux container. +// Returns the count from the first matching pod. func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, namespace, labelName, labelValue, containerName, processName string) (int, error) { @@ -570,6 +570,28 @@ func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, return count, nil } +// CountWindowsProcessInstances counts instances of a process in a Windows container using PowerShell. +// Returns the count from the first matching pod. +func CountWindowsProcessInstances(client *kubernetes.Clientset, config *rest.Config, + namespace, labelName, labelValue, containerName, processName string) (int, error) { + + pods, err := GetPodsWithLabel(client, namespace, labelName, labelValue) + if err != nil { + return 0, err + } + + command := []string{"powershell", "-Command", + fmt.Sprintf("@(Get-Process -Name '%s' -ErrorAction SilentlyContinue).Count", processName)} + stdout, _, err := ExecCmd(client, config, pods[0].Name, containerName, namespace, command) + if err != nil { + return 0, err + } + + count := 0 + fmt.Sscanf(strings.TrimSpace(stdout), "%d", &count) + return count, nil +} + // CheckFileForErrors checks if a specific file in a linux container contains errors. // It tolerates intermittent errors up to 10 occurrences per pattern. func CheckFileForErrors(clientset *kubernetes.Clientset, Cfg *rest.Config, namespace, labelName, labelValue, containerName, filePath string) error { From 9b46a5180931763c67899917bc7bfd8047ae313b Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 10 Apr 2026 23:13:48 -0700 Subject: [PATCH 05/26] fix: RS telegraf default expected count should be 0, not 1 Telegraf is off by default in ama-logs-rs. It only starts when prometheus_data_collection_settings.cluster has urls or kubernetes_services configured. --- test/ginkgo-e2e/configprocessing/configprocessing_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_test.go index eab2a29aa..71f49adc7 100644 --- a/test/ginkgo-e2e/configprocessing/configprocessing_test.go +++ b/test/ginkgo-e2e/configprocessing/configprocessing_test.go @@ -30,8 +30,8 @@ var _ = DescribeTable("Linux process count matches expected", Entry("ama-logs DS: 1 telegraf with default config", "component", "ama-logs-agent", "ama-logs", "telegraf", 1, Label(utils.ConfigProcessMetricsDefault)), - Entry("ama-logs-rs: 1 telegraf with default config", - "rsName", "ama-logs-rs", "ama-logs", "telegraf", 1, + Entry("ama-logs-rs: 0 telegraf with default config", + "rsName", "ama-logs-rs", "ama-logs", "telegraf", 0, Label(utils.ConfigProcessMetricsDefault)), Entry("ama-logs-prometheus: 0 telegraf with default config", "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 0, From 6a9ec42abcdffa63101c6a719692d85f81efe9af Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Mon, 13 Apr 2026 17:17:56 -0700 Subject: [PATCH 06/26] add indirect dependencies to configprocessing go.mod --- test/ginkgo-e2e/configprocessing/go.mod | 62 +++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/test/ginkgo-e2e/configprocessing/go.mod b/test/ginkgo-e2e/configprocessing/go.mod index dd46fee0b..68efd2ea6 100644 --- a/test/ginkgo-e2e/configprocessing/go.mod +++ b/test/ginkgo-e2e/configprocessing/go.mod @@ -10,3 +10,65 @@ require ( github.com/onsi/gomega v1.38.2 k8s.io/client-go v0.35.3 ) + +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/moby/spdystream v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.38.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.35.3 // indirect + k8s.io/apimachinery v0.35.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) From e0f7d2dea88d1231f19c4daac80a4bdfd99d6670 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Mon, 13 Apr 2026 17:48:46 -0700 Subject: [PATCH 07/26] fix: filter for Running pods and correct RS expected count - Add getFirstRunningPod() to skip errored/terminated pods when counting processes, preventing exec failures on non-running pods - RS expected telegraf count when process-metrics-enabled should be 1 (only procstat), not 2 (main telegraf requires prometheus cluster config) --- .../configprocessing/configprocessing_test.go | 4 +-- test/ginkgo-e2e/utils/kubernetes_api_utils.go | 26 ++++++++++++++++--- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_test.go index 71f49adc7..2c3c0c45c 100644 --- a/test/ginkgo-e2e/configprocessing/configprocessing_test.go +++ b/test/ginkgo-e2e/configprocessing/configprocessing_test.go @@ -19,8 +19,8 @@ var _ = DescribeTable("Linux process count matches expected", Entry("ama-logs DS: 2 telegraf when process metrics enabled", "component", "ama-logs-agent", "ama-logs", "telegraf", 2, Label(utils.ConfigProcessMetricsEnabled)), - Entry("ama-logs-rs: 2 telegraf when process metrics enabled", - "rsName", "ama-logs-rs", "ama-logs", "telegraf", 2, + Entry("ama-logs-rs: 1 telegraf when process metrics enabled", + "rsName", "ama-logs-rs", "ama-logs", "telegraf", 1, Label(utils.ConfigProcessMetricsEnabled)), Entry("ama-logs-prometheus: 1 telegraf when process metrics enabled", "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 1, diff --git a/test/ginkgo-e2e/utils/kubernetes_api_utils.go b/test/ginkgo-e2e/utils/kubernetes_api_utils.go index 999365aa2..a87c59f67 100644 --- a/test/ginkgo-e2e/utils/kubernetes_api_utils.go +++ b/test/ginkgo-e2e/utils/kubernetes_api_utils.go @@ -548,8 +548,18 @@ func GetAllNodes(clientset *kubernetes.Clientset) ([]corev1.Node, error) { return nodes.Items, nil } +// getFirstRunningPod returns the first pod in Running phase from the list. +func getFirstRunningPod(pods []corev1.Pod) (corev1.Pod, error) { + for _, pod := range pods { + if pod.Status.Phase == corev1.PodRunning { + return pod, nil + } + } + return corev1.Pod{}, fmt.Errorf("no running pods found (total pods: %d)", len(pods)) +} + // CountProcessInstances counts instances of a process in a Linux container. -// Returns the count from the first matching pod. +// Returns the count from the first running pod. func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, namespace, labelName, labelValue, containerName, processName string) (int, error) { @@ -557,10 +567,14 @@ func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, if err != nil { return 0, err } + pod, err := getFirstRunningPod(pods) + if err != nil { + return 0, err + } command := []string{"bash", "-c", fmt.Sprintf("ps aux | grep '%s' | grep -v grep | wc -l", processName)} - stdout, _, err := ExecCmd(client, config, pods[0].Name, containerName, namespace, command) + stdout, _, err := ExecCmd(client, config, pod.Name, containerName, namespace, command) if err != nil { return 0, err } @@ -571,7 +585,7 @@ func CountProcessInstances(client *kubernetes.Clientset, config *rest.Config, } // CountWindowsProcessInstances counts instances of a process in a Windows container using PowerShell. -// Returns the count from the first matching pod. +// Returns the count from the first running pod. func CountWindowsProcessInstances(client *kubernetes.Clientset, config *rest.Config, namespace, labelName, labelValue, containerName, processName string) (int, error) { @@ -579,10 +593,14 @@ func CountWindowsProcessInstances(client *kubernetes.Clientset, config *rest.Con if err != nil { return 0, err } + pod, err := getFirstRunningPod(pods) + if err != nil { + return 0, err + } command := []string{"powershell", "-Command", fmt.Sprintf("@(Get-Process -Name '%s' -ErrorAction SilentlyContinue).Count", processName)} - stdout, _, err := ExecCmd(client, config, pods[0].Name, containerName, namespace, command) + stdout, _, err := ExecCmd(client, config, pod.Name, containerName, namespace, command) if err != nil { return 0, err } From 3b9e40a493e9f1f39e1a099b8b52b64c0637349f Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 15:59:47 -0700 Subject: [PATCH 08/26] fix: wait for TestKube API server readiness instead of blind sleep --- .pipelines/azure-pipeline-config-tests.yaml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 715a0d2cb..a08343851 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -111,8 +111,12 @@ stages: # Apply RBAC kubectl apply -f ./api-server-permissions.yaml - echo "Waiting for TestKube to be ready..." - sleep 60 + echo "Waiting for TestKube API server to be ready..." + kubectl rollout status deployment/testkube-api-server -n testkube --timeout=300s + echo "Waiting for TestKube operator to be ready..." + kubectl rollout status deployment/testkube-operator-controller-manager -n testkube --timeout=120s + # Give the API server a moment to finish initialization after pod is ready + sleep 15 workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: 'Install TestKube on cluster' From cdc9be8a8fb915754dccb5229478987442f24edc Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 21:57:09 -0700 Subject: [PATCH 09/26] fix: enable testkube-operator for CRD installation on fresh clusters --- .pipelines/azure-pipeline-config-tests.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index a08343851..2356578da 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -106,7 +106,9 @@ stages: # Install TestKube helm repo add kubeshop https://kubeshop.github.io/helm-charts helm repo update - helm upgrade --install --create-namespace testkube kubeshop/testkube -n testkube -f ./helm-testkube-values.yaml + helm upgrade --install --create-namespace testkube kubeshop/testkube -n testkube \ + -f ./helm-testkube-values.yaml \ + --set testkube-operator.enabled=true # Apply RBAC kubectl apply -f ./api-server-permissions.yaml From 5ddc430a0d055c8dda349e0c5bc8c38e0bbc3721 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 21:58:03 -0700 Subject: [PATCH 10/26] chore: add default values for cluster params for quick testing --- .pipelines/azure-pipeline-config-tests.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 2356578da..74b0af6a8 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -9,13 +9,15 @@ parameters: - name: clusterName displayName: 'AKS Cluster Name' type: string + default: 'zane-configmap-test' - name: clusterResourceGroup displayName: 'AKS Cluster Resource Group' type: string + default: 'zane-config-test' - name: branch displayName: 'Git branch for TestKube workflows' type: string - default: 'ci_prod' + default: 'zane/configmap-testing-pipeline' stages: - stage: ConfigMapTests From 163f459d4167d142556ade58e054762451082866 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 22:28:51 -0700 Subject: [PATCH 11/26] fix: pre-install TestKube CRDs instead of enabling operator The operator image (docker.io/kubeshop/testkube-operator) fails to pull on fresh clusters. Instead, extract CRDs from the chart via helm template and apply them before the main install, keeping the operator disabled. This matches existing CI clusters which have CRDs from prior installs. --- .pipelines/azure-pipeline-config-tests.yaml | 34 ++++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 74b0af6a8..f92ba450e 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -105,20 +105,44 @@ stages: sleep 30 fi - # Install TestKube + # Add Helm repo helm repo add kubeshop https://kubeshop.github.io/helm-charts helm repo update - helm upgrade --install --create-namespace testkube kubeshop/testkube -n testkube \ + + # Pre-install CRDs from the chart so post-install hooks can create + # TestWorkflowTemplate resources. The operator is disabled in values + # (existing CI clusters already have CRDs from prior installs). + echo "Pre-installing TestKube CRDs from chart..." + helm template testkube kubeshop/testkube -n testkube \ -f ./helm-testkube-values.yaml \ - --set testkube-operator.enabled=true + --set testkube-operator.enabled=true \ + --show-only 'charts/testkube-operator/templates/crds/*.yaml' \ + | kubectl apply --server-side -f - 2>/dev/null || { + echo "Helm template CRD extraction failed, trying direct CRD apply..." + # Fallback: pull chart and apply CRDs directory + helm pull kubeshop/testkube --untar --untardir /tmp/testkube-chart + if [ -d /tmp/testkube-chart/testkube/charts/testkube-operator/crds ]; then + kubectl apply --server-side -f /tmp/testkube-chart/testkube/charts/testkube-operator/crds/ + elif [ -d /tmp/testkube-chart/testkube/charts/testkube-operator/templates/crds ]; then + kubectl apply --server-side -f /tmp/testkube-chart/testkube/charts/testkube-operator/templates/crds/ + fi + rm -rf /tmp/testkube-chart + } + + echo "Waiting for CRDs to be established..." + for crd in testworkflows.testworkflows.testkube.io testworkflowtemplates.testworkflows.testkube.io testworkflowexecutions.testworkflows.testkube.io; do + kubectl wait --for=condition=Established crd/"$crd" --timeout=60s || echo "Warning: CRD $crd not yet established" + done + + # Install TestKube (operator stays DISABLED — CRDs already in place) + helm upgrade --install --create-namespace testkube kubeshop/testkube -n testkube \ + -f ./helm-testkube-values.yaml # Apply RBAC kubectl apply -f ./api-server-permissions.yaml echo "Waiting for TestKube API server to be ready..." kubectl rollout status deployment/testkube-api-server -n testkube --timeout=300s - echo "Waiting for TestKube operator to be ready..." - kubectl rollout status deployment/testkube-operator-controller-manager -n testkube --timeout=120s # Give the API server a moment to finish initialization after pod is ready sleep 15 workingDirectory: $(Build.SourcesDirectory)/test/testkube From d72c18931a7000625bc9b1714975eb97c7aaf9c2 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 22:47:45 -0700 Subject: [PATCH 12/26] fix: use exact CRD template path instead of glob for helm template --show-only doesn't support globs. The CRDs are in a single file: charts/testkube-operator/templates/crds.yaml (gated by installCRD). Also add explicit --set testkube-operator.installCRD=true. --- .pipelines/azure-pipeline-config-tests.yaml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index f92ba450e..2d9721099 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -116,18 +116,9 @@ stages: helm template testkube kubeshop/testkube -n testkube \ -f ./helm-testkube-values.yaml \ --set testkube-operator.enabled=true \ - --show-only 'charts/testkube-operator/templates/crds/*.yaml' \ - | kubectl apply --server-side -f - 2>/dev/null || { - echo "Helm template CRD extraction failed, trying direct CRD apply..." - # Fallback: pull chart and apply CRDs directory - helm pull kubeshop/testkube --untar --untardir /tmp/testkube-chart - if [ -d /tmp/testkube-chart/testkube/charts/testkube-operator/crds ]; then - kubectl apply --server-side -f /tmp/testkube-chart/testkube/charts/testkube-operator/crds/ - elif [ -d /tmp/testkube-chart/testkube/charts/testkube-operator/templates/crds ]; then - kubectl apply --server-side -f /tmp/testkube-chart/testkube/charts/testkube-operator/templates/crds/ - fi - rm -rf /tmp/testkube-chart - } + --set testkube-operator.installCRD=true \ + --show-only charts/testkube-operator/templates/crds.yaml \ + | kubectl apply --server-side -f - echo "Waiting for CRDs to be established..." for crd in testworkflows.testworkflows.testkube.io testworkflowtemplates.testworkflows.testkube.io testworkflowexecutions.testworkflows.testkube.io; do From eddd9ec0551fd1ee0dbb460aa577e990109a568f Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 23:07:53 -0700 Subject: [PATCH 13/26] fix: label pre-installed CRDs for Helm ownership adoption CRDs created via kubectl apply lack Helm metadata labels/annotations. Helm refuses to install if it can't import them into the release. Add app.kubernetes.io/managed-by=Helm label and release annotations to all testkube CRDs after pre-installing them. --- .pipelines/azure-pipeline-config-tests.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 2d9721099..560028469 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -120,6 +120,14 @@ stages: --show-only charts/testkube-operator/templates/crds.yaml \ | kubectl apply --server-side -f - + # Label/annotate CRDs so Helm adopts them as part of the "testkube" release + echo "Labeling CRDs for Helm ownership..." + for crd in $(kubectl get crds -o name | grep testkube); do + kubectl label "$crd" app.kubernetes.io/managed-by=Helm --overwrite + kubectl annotate "$crd" meta.helm.sh/release-name=testkube --overwrite + kubectl annotate "$crd" meta.helm.sh/release-namespace=testkube --overwrite + done + echo "Waiting for CRDs to be established..." for crd in testworkflows.testworkflows.testkube.io testworkflowtemplates.testworkflows.testkube.io testworkflowexecutions.testworkflows.testkube.io; do kubectl wait --for=condition=Established crd/"$crd" --timeout=60s || echo "Warning: CRD $crd not yet established" From bf3c71b9012b8f96ebce02b176b368c15532791d Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 23:48:48 -0700 Subject: [PATCH 14/26] feat: add Helm deploy stage to deploy ama-logs before config tests --- .pipelines/azure-pipeline-config-tests.yaml | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 560028469..f854e2a7f 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -18,9 +18,41 @@ parameters: displayName: 'Git branch for TestKube workflows' type: string default: 'zane/configmap-testing-pipeline' + - name: amalogsLinuxImage + displayName: 'ama-logs Linux image tag' + type: string + default: '3.1.35-6-gbadded121-20260410023110' + - name: amalogsWindowsImage + displayName: 'ama-logs Windows image tag' + type: string + default: 'win-3.1.35-6-gbadded121-20260410023110' + - name: imageRepository + displayName: 'Image repository path' + type: string + default: '/azuremonitor/containerinsights/cidev' + - name: deployEnvironment + displayName: 'ADO Environment for deployment approval' + type: string + default: 'Zane-ConfigTest-Deploy' stages: +- stage: Deploy + displayName: 'Deploy ama-logs' + jobs: + - template: .pipelines/helm-deploy-templates/ama-logs-helm-deploy.yaml@self + parameters: + clusterName: ${{ parameters.clusterName }} + resourceGroup: ${{ parameters.clusterResourceGroup }} + region: 'uksouth' + subscriptionId: '9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb' + workspaceId: '9906d02f-e852-4559-8291-3a2b241f909b' + amalogsLinuxImage: ${{ parameters.amalogsLinuxImage }} + amalogsWindowsImage: ${{ parameters.amalogsWindowsImage }} + imageRepository: ${{ parameters.imageRepository }} + environment: ${{ parameters.deployEnvironment }} + - stage: ConfigMapTests + dependsOn: Deploy jobs: - job: RunConfigMapTests timeoutInMinutes: 120 From a5e3bfe938c30ac630fdc6961a021ff2067b2963 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 14 Apr 2026 23:56:20 -0700 Subject: [PATCH 15/26] fix: use relative template path for helm deploy --- .pipelines/azure-pipeline-config-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index f854e2a7f..00890deb4 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -39,7 +39,7 @@ stages: - stage: Deploy displayName: 'Deploy ama-logs' jobs: - - template: .pipelines/helm-deploy-templates/ama-logs-helm-deploy.yaml@self + - template: helm-deploy-templates/ama-logs-helm-deploy.yaml parameters: clusterName: ${{ parameters.clusterName }} resourceGroup: ${{ parameters.clusterResourceGroup }} From 7283ead15109c2fd6549071f64bcac556cadd322 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Wed, 15 Apr 2026 22:55:21 -0700 Subject: [PATCH 16/26] refactor: use each loop and CRS template for scalable config test scenarios --- .pipelines/azure-pipeline-config-tests.yaml | 45 +++++++++---------- ...nfig-test-process-metrics-enabled-crs.yaml | 30 ------------- ...aml => testkube-config-test-template.yaml} | 6 +-- test/testkube/run-configtest-scenario.sh | 27 ++++++----- 4 files changed, 41 insertions(+), 67 deletions(-) delete mode 100644 test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml rename test/testkube/config-processing-test-crs/{testkube-config-test-process-metrics-default-crs.yaml => testkube-config-test-template.yaml} (78%) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 00890deb4..a5e13ba97 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -34,6 +34,16 @@ parameters: displayName: 'ADO Environment for deployment approval' type: string default: 'Zane-ConfigTest-Deploy' + - name: scenarios + displayName: 'Test scenarios to run' + type: object + default: + - name: process-metrics-enabled + configmap: test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml + label: config-processing-process-metrics-enabled + - name: process-metrics-default + configmap: kubernetes/container-azm-ms-agentconfig.yaml + label: config-processing-process-metrics-default stages: - stage: Deploy @@ -179,29 +189,18 @@ stages: workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: 'Install TestKube on cluster' - # === Scenario 1: process-metrics-enabled === - - bash: | - chmod +x ./run-configtest-scenario.sh - ./run-configtest-scenario.sh \ - --configmap "../../test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml" \ - --crs "./config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml" \ - --scenario "process-metrics-enabled" \ - --branch "${{ parameters.branch }}" - workingDirectory: $(Build.SourcesDirectory)/test/testkube - displayName: "ConfigTest: process-metrics-enabled" - continueOnError: true - - # === Scenario 2: process-metrics-default (restore defaults) === - - bash: | - chmod +x ./run-configtest-scenario.sh - ./run-configtest-scenario.sh \ - --configmap "../../kubernetes/container-azm-ms-agentconfig.yaml" \ - --crs "./config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml" \ - --scenario "process-metrics-default" \ - --branch "${{ parameters.branch }}" - workingDirectory: $(Build.SourcesDirectory)/test/testkube - displayName: "ConfigTest: process-metrics-default" - continueOnError: true + # === Run test scenarios === + - ${{ each scenario in parameters.scenarios }}: + - bash: | + chmod +x ./run-configtest-scenario.sh + ./run-configtest-scenario.sh \ + --configmap "$(Build.SourcesDirectory)/${{ scenario.configmap }}" \ + --scenario "${{ scenario.name }}" \ + --label "${{ scenario.label }}" \ + --branch "${{ parameters.branch }}" + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: "ConfigTest: ${{ scenario.name }}" + continueOnError: true # === Cleanup === - bash: | diff --git a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml b/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml deleted file mode 100644 index 86ebcaf47..000000000 --- a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-enabled-crs.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: testworkflows.testkube.io/v1 -kind: TestWorkflow -metadata: - name: config-test-process-metrics-enabled - namespace: testkube -spec: - config: - GOTOOLCHAIN: - type: string - default: "" - content: - git: - uri: https://github.com/microsoft/Docker-Provider/ - revision: ci_prod - paths: - - test/ginkgo-e2e - steps: - - name: Run test - container: - workingDir: /data/repo/test/ginkgo-e2e - image: cerebro31/ginkgo-test:latest - env: - - name: GOTOOLCHAIN - value: "{{config.GOTOOLCHAIN}}" - shell: | - ginkgo run -r --label-filter "config-processing-process-metrics-enabled" ./configprocessing - pod: - nodeSelector: - kubernetes.io/os: linux - kubernetes.io/arch: amd64 diff --git a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml b/test/testkube/config-processing-test-crs/testkube-config-test-template.yaml similarity index 78% rename from test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml rename to test/testkube/config-processing-test-crs/testkube-config-test-template.yaml index 5dd4b89bf..260f93e9a 100644 --- a/test/testkube/config-processing-test-crs/testkube-config-test-process-metrics-default-crs.yaml +++ b/test/testkube/config-processing-test-crs/testkube-config-test-template.yaml @@ -1,7 +1,7 @@ apiVersion: testworkflows.testkube.io/v1 kind: TestWorkflow metadata: - name: config-test-process-metrics-default + name: config-test-__SCENARIO__ namespace: testkube spec: config: @@ -11,7 +11,7 @@ spec: content: git: uri: https://github.com/microsoft/Docker-Provider/ - revision: ci_prod + revision: __BRANCH__ paths: - test/ginkgo-e2e steps: @@ -23,7 +23,7 @@ spec: - name: GOTOOLCHAIN value: "{{config.GOTOOLCHAIN}}" shell: | - ginkgo run -r --label-filter "config-processing-process-metrics-default" ./configprocessing + ginkgo run -r --label-filter "__LABEL__" ./configprocessing pod: nodeSelector: kubernetes.io/os: linux diff --git a/test/testkube/run-configtest-scenario.sh b/test/testkube/run-configtest-scenario.sh index 54e1f906f..f7453c855 100644 --- a/test/testkube/run-configtest-scenario.sh +++ b/test/testkube/run-configtest-scenario.sh @@ -5,34 +5,36 @@ set -euo pipefail # Usage: # ./run-configtest-scenario.sh \ # --configmap \ -# --crs \ # --scenario \ +# --label \ # --branch # # Steps: # 1. Apply the configmap variant # 2. Rollout restart ama-logs workloads # 3. Wait for rollout to complete -# 4. Apply the TestKube workflow CRD +# 4. Generate TestKube workflow CRD from template and apply # 5. Run the testworkflow and collect results CONFIGMAP="" -CRS="" SCENARIO="" +LABEL="" BRANCH="ci_prod" +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +TEMPLATE="${SCRIPT_DIR}/config-processing-test-crs/testkube-config-test-template.yaml" while [[ $# -gt 0 ]]; do case "$1" in --configmap) CONFIGMAP="$2"; shift 2 ;; - --crs) CRS="$2"; shift 2 ;; --scenario) SCENARIO="$2"; shift 2 ;; + --label) LABEL="$2"; shift 2 ;; --branch) BRANCH="$2"; shift 2 ;; *) echo "Unknown argument: $1"; exit 1 ;; esac done -if [[ -z "$CONFIGMAP" || -z "$CRS" || -z "$SCENARIO" ]]; then - echo "Error: --configmap, --crs, and --scenario are required" +if [[ -z "$CONFIGMAP" || -z "$SCENARIO" || -z "$LABEL" ]]; then + echo "Error: --configmap, --scenario, and --label are required" exit 1 fi @@ -56,11 +58,14 @@ kubectl rollout status ds/ama-logs -n kube-system --timeout=5m kubectl rollout status deploy/ama-logs-rs -n kube-system --timeout=5m kubectl rollout status ds/ama-logs-windows -n kube-system --timeout=5m 2>/dev/null || echo "ama-logs-windows rollout status skipped" -# Step 4: Apply the TestKube workflow CRD (with branch override) -echo "Applying TestKube workflow CRD: ${CRS} (branch: ${BRANCH})" -CRS_PATCHED="${CRS%.yaml}-patched.yaml" -sed "s|revision: ci_prod|revision: ${BRANCH}|g" "${CRS}" > "${CRS_PATCHED}" -kubectl apply -f "${CRS_PATCHED}" +# Step 4: Generate TestKube workflow CRD from template and apply +echo "Generating TestKube workflow CRD for scenario: ${SCENARIO} (label: ${LABEL}, branch: ${BRANCH})" +GENERATED="/tmp/testkube-crs-${SCENARIO}.yaml" +sed -e "s|__SCENARIO__|${SCENARIO}|g" \ + -e "s|__BRANCH__|${BRANCH}|g" \ + -e "s|__LABEL__|${LABEL}|g" \ + "${TEMPLATE}" > "${GENERATED}" +kubectl apply -f "${GENERATED}" # Step 5: Run the testworkflow echo "Running testworkflow: ${WORKFLOW_NAME}" From a0d997ad7b3ab4acdb731676974cff6e4fbe50c0 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Fri, 17 Apr 2026 20:52:12 -0700 Subject: [PATCH 17/26] remove helm install --- .pipelines/azure-pipeline-config-tests.yaml | 36 ++------------------- 1 file changed, 2 insertions(+), 34 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index a5e13ba97..a99306262 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -9,31 +9,15 @@ parameters: - name: clusterName displayName: 'AKS Cluster Name' type: string - default: 'zane-configmap-test' + default: 'ci-logs-dev-aks-std-prof-config-test1' - name: clusterResourceGroup displayName: 'AKS Cluster Resource Group' type: string - default: 'zane-config-test' + default: 'ci-logs-dev-aks-configmap-test' - name: branch displayName: 'Git branch for TestKube workflows' type: string default: 'zane/configmap-testing-pipeline' - - name: amalogsLinuxImage - displayName: 'ama-logs Linux image tag' - type: string - default: '3.1.35-6-gbadded121-20260410023110' - - name: amalogsWindowsImage - displayName: 'ama-logs Windows image tag' - type: string - default: 'win-3.1.35-6-gbadded121-20260410023110' - - name: imageRepository - displayName: 'Image repository path' - type: string - default: '/azuremonitor/containerinsights/cidev' - - name: deployEnvironment - displayName: 'ADO Environment for deployment approval' - type: string - default: 'Zane-ConfigTest-Deploy' - name: scenarios displayName: 'Test scenarios to run' type: object @@ -46,23 +30,7 @@ parameters: label: config-processing-process-metrics-default stages: -- stage: Deploy - displayName: 'Deploy ama-logs' - jobs: - - template: helm-deploy-templates/ama-logs-helm-deploy.yaml - parameters: - clusterName: ${{ parameters.clusterName }} - resourceGroup: ${{ parameters.clusterResourceGroup }} - region: 'uksouth' - subscriptionId: '9b96ebbd-c57a-42d1-bbe9-b69296e4c7fb' - workspaceId: '9906d02f-e852-4559-8291-3a2b241f909b' - amalogsLinuxImage: ${{ parameters.amalogsLinuxImage }} - amalogsWindowsImage: ${{ parameters.amalogsWindowsImage }} - imageRepository: ${{ parameters.imageRepository }} - environment: ${{ parameters.deployEnvironment }} - - stage: ConfigMapTests - dependsOn: Deploy jobs: - job: RunConfigMapTests timeoutInMinutes: 120 From bffa2c90c16c399d56e7294e65b5c5253f9563de Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Sun, 19 Apr 2026 00:20:45 -0700 Subject: [PATCH 18/26] refactor --- .pipelines/azure-pipeline-config-tests.yaml | 27 ++-- .../configprocessing/configprocessing_test.go | 58 --------- .../countprocess_suite_test.go} | 6 +- .../countprocess/countprocess_test.go | 73 +++++++++++ .../{configprocessing => countprocess}/go.mod | 2 +- .../{configprocessing => countprocess}/go.sum | 0 test/ginkgo-e2e/utils/constants.go | 4 - .../testkube-config-test-template.yaml | 30 ----- .../install-and-execute-testkube-tests.sh | 101 ++++++++++++++- test/testkube/run-configtest-scenario.sh | 115 ------------------ test/testkube/testkube-test-crs.yaml | 52 ++++++++ 11 files changed, 248 insertions(+), 220 deletions(-) delete mode 100644 test/ginkgo-e2e/configprocessing/configprocessing_test.go rename test/ginkgo-e2e/{configprocessing/configprocessing_suite_test.go => countprocess/countprocess_suite_test.go} (76%) create mode 100644 test/ginkgo-e2e/countprocess/countprocess_test.go rename test/ginkgo-e2e/{configprocessing => countprocess}/go.mod (98%) rename test/ginkgo-e2e/{configprocessing => countprocess}/go.sum (100%) delete mode 100644 test/testkube/config-processing-test-crs/testkube-config-test-template.yaml delete mode 100644 test/testkube/run-configtest-scenario.sh diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index a99306262..5e809a1af 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -24,10 +24,14 @@ parameters: default: - name: process-metrics-enabled configmap: test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml - label: config-processing-process-metrics-enabled + workflows: >- + countprocess:EXPECTED_TELEGRAF_DS=2,EXPECTED_TELEGRAF_RS=1,EXPECTED_TELEGRAF_PROMETHEUS=1,EXPECTED_TELEGRAF_WINDOWS=1 + |querylogs: - name: process-metrics-default configmap: kubernetes/container-azm-ms-agentconfig.yaml - label: config-processing-process-metrics-default + workflows: >- + countprocess:EXPECTED_TELEGRAF_DS=1,EXPECTED_TELEGRAF_RS=0,EXPECTED_TELEGRAF_PROMETHEUS=0,EXPECTED_TELEGRAF_WINDOWS=0 + |containerstatus-linux: stages: - stage: ConfigMapTests @@ -157,15 +161,22 @@ stages: workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: 'Install TestKube on cluster' + # Apply TestWorkflow CRs (includes countprocess and others) + - bash: | + kubectl apply -f ./testkube-test-crs.yaml + echo "Waiting for TestWorkflows to be registered..." + sleep 10 + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: 'Apply TestWorkflow CRs' + # === Run test scenarios === - ${{ each scenario in parameters.scenarios }}: - bash: | - chmod +x ./run-configtest-scenario.sh - ./run-configtest-scenario.sh \ - --configmap "$(Build.SourcesDirectory)/${{ scenario.configmap }}" \ - --scenario "${{ scenario.name }}" \ - --label "${{ scenario.label }}" \ - --branch "${{ parameters.branch }}" + chmod +x ./install-and-execute-testkube-tests.sh + ./install-and-execute-testkube-tests.sh \ + ConfigTestMode=true \ + ConfigMap="$(Build.SourcesDirectory)/${{ scenario.configmap }}" \ + Workflows="${{ scenario.workflows }}" workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: "ConfigTest: ${{ scenario.name }}" continueOnError: true diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_test.go b/test/ginkgo-e2e/configprocessing/configprocessing_test.go deleted file mode 100644 index 2c3c0c45c..000000000 --- a/test/ginkgo-e2e/configprocessing/configprocessing_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package configprocessing_test - -import ( - "docker-provider/test/utils" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -// Linux container process count checks -var _ = DescribeTable("Linux process count matches expected", - func(labelName, labelValue, containerName, processName string, expectedCount int) { - count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", labelName, labelValue, containerName, processName) - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedCount)) - }, - - // === Scenario: process-metrics-enabled === - Entry("ama-logs DS: 2 telegraf when process metrics enabled", - "component", "ama-logs-agent", "ama-logs", "telegraf", 2, - Label(utils.ConfigProcessMetricsEnabled)), - Entry("ama-logs-rs: 1 telegraf when process metrics enabled", - "rsName", "ama-logs-rs", "ama-logs", "telegraf", 1, - Label(utils.ConfigProcessMetricsEnabled)), - Entry("ama-logs-prometheus: 1 telegraf when process metrics enabled", - "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 1, - Label(utils.ConfigProcessMetricsEnabled)), - - // === Scenario: process-metrics-default === - Entry("ama-logs DS: 1 telegraf with default config", - "component", "ama-logs-agent", "ama-logs", "telegraf", 1, - Label(utils.ConfigProcessMetricsDefault)), - Entry("ama-logs-rs: 0 telegraf with default config", - "rsName", "ama-logs-rs", "ama-logs", "telegraf", 0, - Label(utils.ConfigProcessMetricsDefault)), - Entry("ama-logs-prometheus: 0 telegraf with default config", - "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf", 0, - Label(utils.ConfigProcessMetricsDefault)), -) - -// Windows container process count checks (uses PowerShell instead of bash) -var _ = DescribeTable("Windows process count matches expected", - func(labelName, labelValue, containerName, processName string, expectedCount int) { - count, err := utils.CountWindowsProcessInstances(K8sClient, Cfg, "kube-system", labelName, labelValue, containerName, processName) - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedCount)) - }, - - // === Scenario: process-metrics-enabled === - Entry("ama-logs-windows: 1 telegraf when process metrics enabled", - "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 1, - Label(utils.ConfigProcessMetricsEnabled)), - - // === Scenario: process-metrics-default === - Entry("ama-logs-windows: 0 telegraf with default config", - "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf", 0, - Label(utils.ConfigProcessMetricsDefault)), -) diff --git a/test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go b/test/ginkgo-e2e/countprocess/countprocess_suite_test.go similarity index 76% rename from test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go rename to test/ginkgo-e2e/countprocess/countprocess_suite_test.go index c71a7d139..3a3208560 100644 --- a/test/ginkgo-e2e/configprocessing/configprocessing_suite_test.go +++ b/test/ginkgo-e2e/countprocess/countprocess_suite_test.go @@ -1,4 +1,4 @@ -package configprocessing_test +package countprocess_test import ( "testing" @@ -14,9 +14,9 @@ import ( var K8sClient *kubernetes.Clientset var Cfg *rest.Config -func TestConfigProcessing(t *testing.T) { +func TestCountProcess(t *testing.T) { RegisterFailHandler(Fail) - RunSpecs(t, "ConfigMap Processing Test Suite") + RunSpecs(t, "Count Process Test Suite") } var _ = BeforeSuite(func() { diff --git a/test/ginkgo-e2e/countprocess/countprocess_test.go b/test/ginkgo-e2e/countprocess/countprocess_test.go new file mode 100644 index 000000000..6834d262f --- /dev/null +++ b/test/ginkgo-e2e/countprocess/countprocess_test.go @@ -0,0 +1,73 @@ +package countprocess_test + +import ( + "fmt" + "os" + "strconv" + + "docker-provider/test/utils" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +// envInt reads an integer from an environment variable, returning defaultVal if unset or invalid. +func envInt(key string, defaultVal int) int { + v := os.Getenv(key) + if v == "" { + return defaultVal + } + n, err := strconv.Atoi(v) + if err != nil { + return defaultVal + } + return n +} + +var _ = Describe("Process count validation", func() { + var ( + expectedTelegrafDS int + expectedTelegrafRS int + expectedTelegrafPrometheus int + expectedTelegrafWindows int + ) + + BeforeEach(func() { + expectedTelegrafDS = envInt("EXPECTED_TELEGRAF_DS", 1) + expectedTelegrafRS = envInt("EXPECTED_TELEGRAF_RS", 0) + expectedTelegrafPrometheus = envInt("EXPECTED_TELEGRAF_PROMETHEUS", 0) + expectedTelegrafWindows = envInt("EXPECTED_TELEGRAF_WINDOWS", 0) + }) + + It("ama-logs DS has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent", "ama-logs", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafDS), + fmt.Sprintf("expected %d telegraf in ama-logs DS, got %d", expectedTelegrafDS, count)) + }) + + It("ama-logs-rs has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "rsName", "ama-logs-rs", "ama-logs", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafRS), + fmt.Sprintf("expected %d telegraf in ama-logs-rs, got %d", expectedTelegrafRS, count)) + }) + + It("ama-logs-prometheus has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafPrometheus), + fmt.Sprintf("expected %d telegraf in ama-logs-prometheus, got %d", expectedTelegrafPrometheus, count)) + }) + + It("ama-logs-windows has expected telegraf count", func() { + count, err := utils.CountWindowsProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafWindows), + fmt.Sprintf("expected %d telegraf in ama-logs-windows, got %d", expectedTelegrafWindows, count)) + }) +}) diff --git a/test/ginkgo-e2e/configprocessing/go.mod b/test/ginkgo-e2e/countprocess/go.mod similarity index 98% rename from test/ginkgo-e2e/configprocessing/go.mod rename to test/ginkgo-e2e/countprocess/go.mod index 68efd2ea6..794440de1 100644 --- a/test/ginkgo-e2e/configprocessing/go.mod +++ b/test/ginkgo-e2e/countprocess/go.mod @@ -1,4 +1,4 @@ -module docker-provider/test/configprocessing +module docker-provider/test/countprocess go 1.26.1 diff --git a/test/ginkgo-e2e/configprocessing/go.sum b/test/ginkgo-e2e/countprocess/go.sum similarity index 100% rename from test/ginkgo-e2e/configprocessing/go.sum rename to test/ginkgo-e2e/countprocess/go.sum diff --git a/test/ginkgo-e2e/utils/constants.go b/test/ginkgo-e2e/utils/constants.go index cf3922dea..a5bb73f86 100644 --- a/test/ginkgo-e2e/utils/constants.go +++ b/test/ginkgo-e2e/utils/constants.go @@ -24,8 +24,4 @@ const ( // IntermittentErrorThreshold is the maximum number of occurrences allowed for expected intermittent errors IntermittentErrorThreshold = 10 - - // ConfigMap processing test scenario labels - ConfigProcessMetricsEnabled = "config-processing-process-metrics-enabled" - ConfigProcessMetricsDefault = "config-processing-process-metrics-default" ) diff --git a/test/testkube/config-processing-test-crs/testkube-config-test-template.yaml b/test/testkube/config-processing-test-crs/testkube-config-test-template.yaml deleted file mode 100644 index 260f93e9a..000000000 --- a/test/testkube/config-processing-test-crs/testkube-config-test-template.yaml +++ /dev/null @@ -1,30 +0,0 @@ -apiVersion: testworkflows.testkube.io/v1 -kind: TestWorkflow -metadata: - name: config-test-__SCENARIO__ - namespace: testkube -spec: - config: - GOTOOLCHAIN: - type: string - default: "" - content: - git: - uri: https://github.com/microsoft/Docker-Provider/ - revision: __BRANCH__ - paths: - - test/ginkgo-e2e - steps: - - name: Run test - container: - workingDir: /data/repo/test/ginkgo-e2e - image: cerebro31/ginkgo-test:latest - env: - - name: GOTOOLCHAIN - value: "{{config.GOTOOLCHAIN}}" - shell: | - ginkgo run -r --label-filter "__LABEL__" ./configprocessing - pod: - nodeSelector: - kubernetes.io/os: linux - kubernetes.io/arch: amd64 diff --git a/test/testkube/install-and-execute-testkube-tests.sh b/test/testkube/install-and-execute-testkube-tests.sh index 75e52d9dd..14593003a 100644 --- a/test/testkube/install-and-execute-testkube-tests.sh +++ b/test/testkube/install-and-execute-testkube-tests.sh @@ -1,9 +1,13 @@ #!/bin/bash +ConfigTestMode=false +ConfigMap="" +Workflows="" + for ARGUMENT in "$@" do KEY=$(echo $ARGUMENT | cut -f1 -d=) - VALUE=$(echo $ARGUMENT | cut -f2 -d=) + VALUE=$(echo $ARGUMENT | cut -f2- -d=) case "$KEY" in AzureClientId) AzureClientId=$VALUE ;; @@ -11,6 +15,9 @@ do TeamsWebhookUri) TeamsWebhookUri=$VALUE ;; LinuxTestsOnly) LinuxTestsOnly=$VALUE ;; GenevaIntegration) GenevaIntegration=$VALUE ;; + ConfigTestMode) ConfigTestMode=$VALUE ;; + ConfigMap) ConfigMap=$VALUE ;; + Workflows) Workflows=$VALUE ;; *) esac done @@ -18,6 +25,98 @@ done cluster="$(kubectl config current-context)" echo "Current cluster: $cluster" +# ============================================================ +# ConfigTest mode: apply configmap, wait, run a single workflow +# Assumes TestKube is already installed by the pipeline setup. +# ============================================================ +if [[ "$ConfigTestMode" == "true" ]]; then + echo "========== ConfigTest Mode ==========" + + if [[ -z "$ConfigMap" || -z "$Workflows" ]]; then + echo "Error: ConfigTestMode requires ConfigMap and Workflows parameters" + exit 1 + fi + + # Apply the configmap variant + echo "Applying configmap: ${ConfigMap}" + kubectl apply -f "${ConfigMap}" + + # Wait for ama-logs to detect the configmap change and restart + echo "Waiting 60s for ama-logs to detect configmap change..." + sleep 60 + + failed_workflows=() + successful_workflows=() + + # Parse workflows: "wf1:key=val,key=val|wf2:key=val|wf3:" + IFS='|' read -ra wf_entries <<< "$Workflows" + for entry in "${wf_entries[@]}"; do + wf_name="${entry%%:*}" + wf_config="${entry#*:}" + + # Build --config flags for this workflow + config_flags="--config GOTOOLCHAIN=auto" + if [[ -n "$wf_config" ]]; then + IFS=',' read -ra pairs <<< "$wf_config" + for pair in "${pairs[@]}"; do + config_flags+=" --config ${pair}" + done + fi + + echo "Running workflow: ${wf_name} with config: ${config_flags}" + kubectl testkube run testworkflow "${wf_name}" ${config_flags} --verbose + + echo "Waiting for execution to be created..." + sleep 5 + + execution_id=$(kubectl testkube get testworkflowexecution | grep -i "${wf_name}" | head -n 1 | awk '{print $1}') + echo "Execution ID: ${execution_id}" + + if [[ -z "${execution_id}" ]]; then + echo "Error: Could not find execution ID for ${wf_name}" + failed_workflows+=("${wf_name} (no execution ID)") + continue + fi + + kubectl testkube watch testworkflowexecution "${execution_id}" + + kubectl testkube get testworkflowexecution "${execution_id}" --output json > "testkube-results-${wf_name}.json" + + if ! jq empty "testkube-results-${wf_name}.json" 2>/dev/null; then + echo "Error: Failed to get valid JSON results for ${wf_name}" + cat "testkube-results-${wf_name}.json" + failed_workflows+=("${wf_name} (invalid JSON)") + continue + fi + + result_status=$(jq -r '.result.status' "testkube-results-${wf_name}.json") + if [[ "${result_status}" == "failed" ]]; then + echo "TestWorkflow FAILED: ${wf_name} (execution: ${execution_id})" + kubectl testkube get testworkflowexecution "${execution_id}" --logs-only + failed_workflows+=("${wf_name} (execution: ${execution_id})") + else + echo "TestWorkflow PASSED: ${wf_name} (execution: ${execution_id})" + successful_workflows+=("${wf_name} (execution: ${execution_id})") + fi + done + + echo "" + echo "========== ConfigTest Summary ==========" + if [[ ${#successful_workflows[@]} -gt 0 ]]; then + echo "Passed:" + for wf in "${successful_workflows[@]}"; do echo " - $wf"; done + fi + if [[ ${#failed_workflows[@]} -gt 0 ]]; then + echo "Failed:" + for wf in "${failed_workflows[@]}"; do echo " - $wf"; done + echo "========================================" + exit 1 + fi + echo "All workflows passed." + echo "========================================" + exit 0 +fi + # Remove stale CRDs that block Helm ownership stale_crds=( "testworkflowexecutions.testworkflows.testkube.io" diff --git a/test/testkube/run-configtest-scenario.sh b/test/testkube/run-configtest-scenario.sh deleted file mode 100644 index f7453c855..000000000 --- a/test/testkube/run-configtest-scenario.sh +++ /dev/null @@ -1,115 +0,0 @@ -#!/bin/bash -set -euo pipefail - -# Generic script for running a single configmap test scenario. -# Usage: -# ./run-configtest-scenario.sh \ -# --configmap \ -# --scenario \ -# --label \ -# --branch -# -# Steps: -# 1. Apply the configmap variant -# 2. Rollout restart ama-logs workloads -# 3. Wait for rollout to complete -# 4. Generate TestKube workflow CRD from template and apply -# 5. Run the testworkflow and collect results - -CONFIGMAP="" -SCENARIO="" -LABEL="" -BRANCH="ci_prod" -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -TEMPLATE="${SCRIPT_DIR}/config-processing-test-crs/testkube-config-test-template.yaml" - -while [[ $# -gt 0 ]]; do - case "$1" in - --configmap) CONFIGMAP="$2"; shift 2 ;; - --scenario) SCENARIO="$2"; shift 2 ;; - --label) LABEL="$2"; shift 2 ;; - --branch) BRANCH="$2"; shift 2 ;; - *) echo "Unknown argument: $1"; exit 1 ;; - esac -done - -if [[ -z "$CONFIGMAP" || -z "$SCENARIO" || -z "$LABEL" ]]; then - echo "Error: --configmap, --scenario, and --label are required" - exit 1 -fi - -WORKFLOW_NAME="config-test-${SCENARIO}" - -echo "========== ConfigTest Scenario: ${SCENARIO} ==========" - -# Step 1: Apply configmap variant -echo "Applying configmap: ${CONFIGMAP}" -kubectl apply -f "${CONFIGMAP}" - -# Step 2: Rollout restart ama-logs workloads -echo "Restarting ama-logs workloads..." -kubectl rollout restart ds/ama-logs -n kube-system -kubectl rollout restart deploy/ama-logs-rs -n kube-system -kubectl rollout restart ds/ama-logs-windows -n kube-system 2>/dev/null || echo "ama-logs-windows daemonset not found (may not exist on this cluster), skipping" - -# Step 3: Wait for rollout to complete -echo "Waiting for rollouts to complete..." -kubectl rollout status ds/ama-logs -n kube-system --timeout=5m -kubectl rollout status deploy/ama-logs-rs -n kube-system --timeout=5m -kubectl rollout status ds/ama-logs-windows -n kube-system --timeout=5m 2>/dev/null || echo "ama-logs-windows rollout status skipped" - -# Step 4: Generate TestKube workflow CRD from template and apply -echo "Generating TestKube workflow CRD for scenario: ${SCENARIO} (label: ${LABEL}, branch: ${BRANCH})" -GENERATED="/tmp/testkube-crs-${SCENARIO}.yaml" -sed -e "s|__SCENARIO__|${SCENARIO}|g" \ - -e "s|__BRANCH__|${BRANCH}|g" \ - -e "s|__LABEL__|${LABEL}|g" \ - "${TEMPLATE}" > "${GENERATED}" -kubectl apply -f "${GENERATED}" - -# Step 5: Run the testworkflow -echo "Running testworkflow: ${WORKFLOW_NAME}" -kubectl testkube run testworkflow "${WORKFLOW_NAME}" \ - --config GOTOOLCHAIN="auto" \ - --verbose - -echo "Waiting for execution to be created..." -sleep 5 - -echo "Fetching testworkflow executions for ${WORKFLOW_NAME}..." -kubectl testkube get testworkflowexecution -execution_id=$(kubectl testkube get testworkflowexecution | grep -i "${WORKFLOW_NAME}" | head -n 1 | awk '{print $1}') - -echo "Execution ID: ${execution_id}" - -if [[ -z "${execution_id}" ]]; then - echo "Error: Could not find execution ID for ${WORKFLOW_NAME}" - exit 1 -fi - -# Watch until the testworkflow finishes -kubectl testkube watch testworkflowexecution "${execution_id}" - -# Get the results as a formatted JSON file -kubectl testkube get testworkflowexecution "${execution_id}" --output json > "testkube-results-${SCENARIO}.json" - -# Verify the JSON is valid -if ! jq empty "testkube-results-${SCENARIO}.json" 2>/dev/null; then - echo "Error: Failed to get valid JSON results for scenario ${SCENARIO}" - echo "Contents of testkube-results-${SCENARIO}.json:" - cat "testkube-results-${SCENARIO}.json" - exit 1 -fi - -# Check result status -result_status=$(jq -r '.result.status' "testkube-results-${SCENARIO}.json") -if [[ "${result_status}" == "failed" ]]; then - echo "TestWorkflow FAILED for scenario: ${SCENARIO} (execution: ${execution_id})" - kubectl testkube get testworkflowexecution "${execution_id}" --logs-only > "execution-${SCENARIO}.log" 2>&1 - cat "execution-${SCENARIO}.log" - exit 1 -else - echo "TestWorkflow PASSED for scenario: ${SCENARIO} (execution: ${execution_id})" -fi - -echo "========== Scenario ${SCENARIO} complete ==========" diff --git a/test/testkube/testkube-test-crs.yaml b/test/testkube/testkube-test-crs.yaml index f3ce2d65e..78fa2eb1f 100644 --- a/test/testkube/testkube-test-crs.yaml +++ b/test/testkube/testkube-test-crs.yaml @@ -148,6 +148,58 @@ spec: - name: GOTOOLCHAIN value: "{{config.GOTOOLCHAIN}}" shell: ginkgo ./querylogs + pod: + nodeSelector: + kubernetes.io/os: linux + kubernetes.io/arch: amd64 +--- +apiVersion: testworkflows.testkube.io/v1 +kind: TestWorkflow +metadata: + name: countprocess + namespace: testkube + labels: + test-type: ginkgo-test +spec: + config: + EXPECTED_TELEGRAF_DS: + type: string + default: "1" + EXPECTED_TELEGRAF_RS: + type: string + default: "0" + EXPECTED_TELEGRAF_PROMETHEUS: + type: string + default: "0" + EXPECTED_TELEGRAF_WINDOWS: + type: string + default: "0" + GOTOOLCHAIN: + type: string + default: "" + content: + git: + uri: https://github.com/microsoft/Docker-Provider/ + revision: ci_prod + paths: + - test/ginkgo-e2e + steps: + - name: Run test + container: + workingDir: /data/repo/test/ginkgo-e2e + image: cerebro31/ginkgo-test:latest + env: + - name: EXPECTED_TELEGRAF_DS + value: "{{config.EXPECTED_TELEGRAF_DS}}" + - name: EXPECTED_TELEGRAF_RS + value: "{{config.EXPECTED_TELEGRAF_RS}}" + - name: EXPECTED_TELEGRAF_PROMETHEUS + value: "{{config.EXPECTED_TELEGRAF_PROMETHEUS}}" + - name: EXPECTED_TELEGRAF_WINDOWS + value: "{{config.EXPECTED_TELEGRAF_WINDOWS}}" + - name: GOTOOLCHAIN + value: "{{config.GOTOOLCHAIN}}" + shell: ginkgo run -r ./countprocess pod: nodeSelector: kubernetes.io/os: linux From fe9bf06dda086050cc257f2250440efc8faa29a5 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Sun, 19 Apr 2026 23:01:13 -0700 Subject: [PATCH 19/26] refactor: replace inline config test scenarios with YAML test matrix Move config test definitions from pipe-delimited workflow strings in the pipeline YAML to a declarative configmap-test-matrix.yaml. A new run-matrix-tests.sh script parses the matrix with yq/jq and runs all cases sequentially. Adding a new scenario is now a single YAML block with no script or pipeline changes needed. --- .pipelines/azure-pipeline-config-tests.yaml | 33 +--- test/testkube/configmap-test-matrix.yaml | 36 +++++ test/testkube/run-matrix-tests.sh | 165 ++++++++++++++++++++ 3 files changed, 209 insertions(+), 25 deletions(-) create mode 100644 test/testkube/configmap-test-matrix.yaml create mode 100644 test/testkube/run-matrix-tests.sh diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 5e809a1af..52f55a472 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -18,20 +18,7 @@ parameters: displayName: 'Git branch for TestKube workflows' type: string default: 'zane/configmap-testing-pipeline' - - name: scenarios - displayName: 'Test scenarios to run' - type: object - default: - - name: process-metrics-enabled - configmap: test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml - workflows: >- - countprocess:EXPECTED_TELEGRAF_DS=2,EXPECTED_TELEGRAF_RS=1,EXPECTED_TELEGRAF_PROMETHEUS=1,EXPECTED_TELEGRAF_WINDOWS=1 - |querylogs: - - name: process-metrics-default - configmap: kubernetes/container-azm-ms-agentconfig.yaml - workflows: >- - countprocess:EXPECTED_TELEGRAF_DS=1,EXPECTED_TELEGRAF_RS=0,EXPECTED_TELEGRAF_PROMETHEUS=0,EXPECTED_TELEGRAF_WINDOWS=0 - |containerstatus-linux: + # Test scenarios are defined in test/testkube/configmap-test-matrix.yaml stages: - stage: ConfigMapTests @@ -169,17 +156,13 @@ stages: workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: 'Apply TestWorkflow CRs' - # === Run test scenarios === - - ${{ each scenario in parameters.scenarios }}: - - bash: | - chmod +x ./install-and-execute-testkube-tests.sh - ./install-and-execute-testkube-tests.sh \ - ConfigTestMode=true \ - ConfigMap="$(Build.SourcesDirectory)/${{ scenario.configmap }}" \ - Workflows="${{ scenario.workflows }}" - workingDirectory: $(Build.SourcesDirectory)/test/testkube - displayName: "ConfigTest: ${{ scenario.name }}" - continueOnError: true + # === Run test matrix === + - bash: | + chmod +x ./run-matrix-tests.sh + ./run-matrix-tests.sh \ + --repo-root "$(Build.SourcesDirectory)" + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: "Run ConfigMap Test Matrix" # === Cleanup === - bash: | diff --git a/test/testkube/configmap-test-matrix.yaml b/test/testkube/configmap-test-matrix.yaml new file mode 100644 index 000000000..e0a656dc2 --- /dev/null +++ b/test/testkube/configmap-test-matrix.yaml @@ -0,0 +1,36 @@ +# configmap-test-matrix.yaml +# Declarative test matrix for ama-logs ConfigMap tests. +# Each case: apply a configmap, then run workflows with specified params. +# +# Schema: +# defaults.params — merged into every workflow (lowest priority) +# case-level params — merged into all workflows in that case (overrides defaults) +# workflow params — merged last (highest priority) +# configmap — path relative to repo root; kubectl apply -f + 60s wait + +defaults: + params: + GOTOOLCHAIN: "auto" + +cases: + - name: process-metrics-enabled + configmap: test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml + workflows: + - name: countprocess + params: + EXPECTED_TELEGRAF_DS: "2" + EXPECTED_TELEGRAF_RS: "1" + EXPECTED_TELEGRAF_PROMETHEUS: "1" + EXPECTED_TELEGRAF_WINDOWS: "1" + - name: querylogs + + - name: process-metrics-default + configmap: kubernetes/container-azm-ms-agentconfig.yaml + workflows: + - name: countprocess + params: + EXPECTED_TELEGRAF_DS: "1" + EXPECTED_TELEGRAF_RS: "0" + EXPECTED_TELEGRAF_PROMETHEUS: "0" + EXPECTED_TELEGRAF_WINDOWS: "0" + - name: containerstatus-linux diff --git a/test/testkube/run-matrix-tests.sh b/test/testkube/run-matrix-tests.sh new file mode 100644 index 000000000..e725edc19 --- /dev/null +++ b/test/testkube/run-matrix-tests.sh @@ -0,0 +1,165 @@ +#!/bin/bash +# run-matrix-tests.sh +# Reads configmap-test-matrix.yaml and runs all cases sequentially. +# Each case: apply configmap, wait, run workflows with merged params. +# +# Usage: ./run-matrix-tests.sh [--matrix ] [--repo-root ] + +set -euo pipefail + +MATRIX_FILE="./configmap-test-matrix.yaml" +REPO_ROOT="${BUILD_SOURCESDIRECTORY:-$(cd ../.. && pwd)}" + +# ── Parse arguments ────────────────────────────────────────── +while [[ $# -gt 0 ]]; do + case "$1" in + --matrix) MATRIX_FILE="$2"; shift 2 ;; + --repo-root) REPO_ROOT="$2"; shift 2 ;; + *) echo "Unknown argument: $1"; exit 1 ;; + esac +done + +# ── Ensure yq is available ─────────────────────────────────── +if ! command -v yq &>/dev/null; then + echo "Installing yq..." + sudo wget -qO /usr/local/bin/yq \ + https://github.com/mikefarah/yq/releases/download/v4.44.1/yq_linux_amd64 + sudo chmod +x /usr/local/bin/yq +fi + +echo "Matrix file: ${MATRIX_FILE}" +echo "Repo root: ${REPO_ROOT}" +echo "" + +# ── Read defaults ──────────────────────────────────────────── +default_params=$(yq -o=json '.defaults.params // {}' "$MATRIX_FILE") +case_count=$(yq '.cases | length' "$MATRIX_FILE") + +if [[ "$case_count" -eq 0 ]]; then + echo "No cases found in ${MATRIX_FILE}" + exit 1 +fi + +# ── Track overall results ──────────────────────────────────── +all_failed=() +all_passed=() + +# ── Run a single workflow ──────────────────────────────────── +run_workflow() { + local wf_name="$1" + local config_flags="$2" + + echo " Running workflow: ${wf_name}" + echo " Config: ${config_flags}" + kubectl testkube run testworkflow "${wf_name}" ${config_flags} --verbose + + echo " Waiting for execution to be created..." + sleep 5 + + local execution_id + execution_id=$(kubectl testkube get testworkflowexecution | grep -i "${wf_name}" | head -n 1 | awk '{print $1}') + echo " Execution ID: ${execution_id}" + + if [[ -z "${execution_id}" ]]; then + echo " Error: Could not find execution ID for ${wf_name}" + return 1 + fi + + kubectl testkube watch testworkflowexecution "${execution_id}" + + kubectl testkube get testworkflowexecution "${execution_id}" --output json > "testkube-results-${wf_name}.json" + + if ! jq empty "testkube-results-${wf_name}.json" 2>/dev/null; then + echo " Error: Failed to get valid JSON results for ${wf_name}" + cat "testkube-results-${wf_name}.json" + return 1 + fi + + local result_status + result_status=$(jq -r '.result.status' "testkube-results-${wf_name}.json") + if [[ "${result_status}" == "failed" ]]; then + echo " TestWorkflow FAILED: ${wf_name} (execution: ${execution_id})" + kubectl testkube get testworkflowexecution "${execution_id}" --logs-only || true + return 1 + else + echo " TestWorkflow PASSED: ${wf_name} (execution: ${execution_id})" + return 0 + fi +} + +# ── Iterate over cases ─────────────────────────────────────── +for (( c=0; c Date: Sun, 19 Apr 2026 23:05:30 -0700 Subject: [PATCH 20/26] test: point countprocess workflow to feature branch for testing --- test/testkube/testkube-test-crs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/testkube/testkube-test-crs.yaml b/test/testkube/testkube-test-crs.yaml index 78fa2eb1f..67f14396e 100644 --- a/test/testkube/testkube-test-crs.yaml +++ b/test/testkube/testkube-test-crs.yaml @@ -180,7 +180,7 @@ spec: content: git: uri: https://github.com/microsoft/Docker-Provider/ - revision: ci_prod + revision: zane/configmap-testing-pipeline paths: - test/ginkgo-e2e steps: From 6b2b6183b716b8be74ccd3ffbd965a379ff96340 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Tue, 21 Apr 2026 15:07:45 -0700 Subject: [PATCH 21/26] refactor effort 2 --- .pipelines/azure-pipeline-config-tests.yaml | 59 ++++++- test/testkube/run-matrix-tests.sh | 163 ++++++++------------ 2 files changed, 121 insertions(+), 101 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 52f55a472..311a2e5e1 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -18,7 +18,13 @@ parameters: displayName: 'Git branch for TestKube workflows' type: string default: 'zane/configmap-testing-pipeline' - # Test scenarios are defined in test/testkube/configmap-test-matrix.yaml + # Case names must match the 'name' field in test/testkube/configmap-test-matrix.yaml + - name: cases + displayName: 'Test cases to run' + type: object + default: + - process-metrics-enabled + - process-metrics-default stages: - stage: ConfigMapTests @@ -156,13 +162,54 @@ stages: workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: 'Apply TestWorkflow CRs' - # === Run test matrix === + # === Validate cases match matrix === - bash: | - chmod +x ./run-matrix-tests.sh - ./run-matrix-tests.sh \ - --repo-root "$(Build.SourcesDirectory)" + set -euo pipefail + + # Install yq if not present + if ! command -v yq &> /dev/null; then + curl -sL https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -o /tmp/yq + chmod +x /tmp/yq + yq="/tmp/yq" + else + yq="yq" + fi + + # Cases from pipeline parameter + echo "$PIPELINE_CASES" | tr ',' '\n' | sed 's/^ *//;s/ *$//' | sort > /tmp/pipeline.txt + + # Cases from matrix YAML + $yq '.cases[].name' ./configmap-test-matrix.yaml | sort > /tmp/matrix.txt + + echo "Pipeline cases:" + cat /tmp/pipeline.txt + echo "" + echo "Matrix cases:" + cat /tmp/matrix.txt + echo "" + + if ! diff /tmp/pipeline.txt /tmp/matrix.txt; then + echo "##[error]Pipeline cases and matrix cases are out of sync!" + echo "Update the 'cases' parameter in azure-pipeline-config-tests.yaml to match configmap-test-matrix.yaml" + exit 1 + fi + + echo "Pipeline cases match matrix cases." workingDirectory: $(Build.SourcesDirectory)/test/testkube - displayName: "Run ConfigMap Test Matrix" + displayName: 'Validate cases match matrix' + env: + PIPELINE_CASES: ${{ join(',', parameters.cases) }} + + # === Run test cases (one step per case) === + - ${{ each caseName in parameters.cases }}: + - bash: | + chmod +x ./run-matrix-tests.sh + ./run-matrix-tests.sh \ + --case "${{ caseName }}" \ + --repo-root "$(Build.SourcesDirectory)" + workingDirectory: $(Build.SourcesDirectory)/test/testkube + displayName: "ConfigTest: ${{ caseName }}" + continueOnError: true # === Cleanup === - bash: | diff --git a/test/testkube/run-matrix-tests.sh b/test/testkube/run-matrix-tests.sh index e725edc19..4b995d196 100644 --- a/test/testkube/run-matrix-tests.sh +++ b/test/testkube/run-matrix-tests.sh @@ -1,24 +1,31 @@ #!/bin/bash # run-matrix-tests.sh -# Reads configmap-test-matrix.yaml and runs all cases sequentially. -# Each case: apply configmap, wait, run workflows with merged params. +# Reads a single case from configmap-test-matrix.yaml, applies its configmap, +# and runs all workflows for that case with merged params. # -# Usage: ./run-matrix-tests.sh [--matrix ] [--repo-root ] +# Usage: ./run-matrix-tests.sh --case [--matrix ] [--repo-root ] set -euo pipefail MATRIX_FILE="./configmap-test-matrix.yaml" REPO_ROOT="${BUILD_SOURCESDIRECTORY:-$(cd ../.. && pwd)}" +CASE_NAME="" # ── Parse arguments ────────────────────────────────────────── while [[ $# -gt 0 ]]; do case "$1" in - --matrix) MATRIX_FILE="$2"; shift 2 ;; + --matrix) MATRIX_FILE="$2"; shift 2 ;; --repo-root) REPO_ROOT="$2"; shift 2 ;; + --case) CASE_NAME="$2"; shift 2 ;; *) echo "Unknown argument: $1"; exit 1 ;; esac done +if [[ -z "$CASE_NAME" ]]; then + echo "Error: --case is required" + exit 1 +fi + # ── Ensure yq is available ─────────────────────────────────── if ! command -v yq &>/dev/null; then echo "Installing yq..." @@ -29,26 +36,56 @@ fi echo "Matrix file: ${MATRIX_FILE}" echo "Repo root: ${REPO_ROOT}" +echo "Case: ${CASE_NAME}" echo "" -# ── Read defaults ──────────────────────────────────────────── +# ── Find the case ─────────────────────────────────────────── +case_index=$(yq ".cases | to_entries | .[] | select(.value.name == \"${CASE_NAME}\") | .key" "$MATRIX_FILE") +if [[ -z "$case_index" ]]; then + echo "Error: case '${CASE_NAME}' not found in ${MATRIX_FILE}" + echo "Available cases:" + yq '.cases[].name' "$MATRIX_FILE" + exit 1 +fi + +# ── Read case data ────────────────────────────────────────── default_params=$(yq -o=json '.defaults.params // {}' "$MATRIX_FILE") -case_count=$(yq '.cases | length' "$MATRIX_FILE") +configmap=$(yq ".cases[${case_index}].configmap // \"\"" "$MATRIX_FILE") +case_params=$(yq -o=json ".cases[${case_index}].params // {}" "$MATRIX_FILE") +wf_count=$(yq ".cases[${case_index}].workflows | length" "$MATRIX_FILE") -if [[ "$case_count" -eq 0 ]]; then - echo "No cases found in ${MATRIX_FILE}" - exit 1 +echo "==========================================" +echo "Case: ${CASE_NAME}" +echo "==========================================" + +# ── Apply configmap if specified ──────────────────────────── +if [[ -n "$configmap" ]]; then + local_path="${REPO_ROOT}/${configmap}" + echo "Applying configmap: ${local_path}" + kubectl apply -f "${local_path}" + echo "Waiting 60s for ama-logs to detect configmap change..." + sleep 60 fi -# ── Track overall results ──────────────────────────────────── -all_failed=() -all_passed=() +# ── Run workflows ─────────────────────────────────────────── +failed=() +passed=() + +for (( w=0; w "testkube-results-${wf_name}.json" if ! jq empty "testkube-results-${wf_name}.json" 2>/dev/null; then echo " Error: Failed to get valid JSON results for ${wf_name}" cat "testkube-results-${wf_name}.json" - return 1 + failed+=("$wf_name") + continue fi - local result_status result_status=$(jq -r '.result.status' "testkube-results-${wf_name}.json") if [[ "${result_status}" == "failed" ]]; then - echo " TestWorkflow FAILED: ${wf_name} (execution: ${execution_id})" + echo " FAILED: ${wf_name} (execution: ${execution_id})" kubectl testkube get testworkflowexecution "${execution_id}" --logs-only || true - return 1 + failed+=("$wf_name") else - echo " TestWorkflow PASSED: ${wf_name} (execution: ${execution_id})" - return 0 - fi -} - -# ── Iterate over cases ─────────────────────────────────────── -for (( c=0; c Date: Tue, 21 Apr 2026 15:53:58 -0700 Subject: [PATCH 22/26] add pipeline vars --- .pipelines/azure-pipeline-config-tests.yaml | 4 ++++ test/testkube/configmap-test-matrix.yaml | 9 ++++++++- test/testkube/run-matrix-tests.sh | 8 ++++++-- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 311a2e5e1..3bf9880a4 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -210,6 +210,10 @@ stages: workingDirectory: $(Build.SourcesDirectory)/test/testkube displayName: "ConfigTest: ${{ caseName }}" continueOnError: true + env: + AZURE_TENANT_ID: $(AZURE_TENANT_ID) + AZURE_CLIENT_ID: $(AZURE_CLIENT_ID) + GENEVA_INTEGRATION: false # === Cleanup === - bash: | diff --git a/test/testkube/configmap-test-matrix.yaml b/test/testkube/configmap-test-matrix.yaml index e0a656dc2..ea745f9b2 100644 --- a/test/testkube/configmap-test-matrix.yaml +++ b/test/testkube/configmap-test-matrix.yaml @@ -6,9 +6,12 @@ # defaults.params — merged into every workflow (lowest priority) # case-level params — merged into all workflows in that case (overrides defaults) # workflow params — merged last (highest priority) -# configmap — path relative to repo root; kubectl apply -f + 60s wait +# configmap — path relative to repo root; kubectl apply -f then wait +# defaults.wait_seconds — global wait time after applying configmap (default: 60) +# case-level wait_seconds — per-case override defaults: + wait_seconds: 600 params: GOTOOLCHAIN: "auto" @@ -23,6 +26,10 @@ cases: EXPECTED_TELEGRAF_PROMETHEUS: "1" EXPECTED_TELEGRAF_WINDOWS: "1" - name: querylogs + params: + AZURE_TENANT_ID: ${AZURE_TENANT_ID} + AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} + GENEVA_INTEGRATION: false - name: process-metrics-default configmap: kubernetes/container-azm-ms-agentconfig.yaml diff --git a/test/testkube/run-matrix-tests.sh b/test/testkube/run-matrix-tests.sh index 4b995d196..bb102afd7 100644 --- a/test/testkube/run-matrix-tests.sh +++ b/test/testkube/run-matrix-tests.sh @@ -50,8 +50,10 @@ fi # ── Read case data ────────────────────────────────────────── default_params=$(yq -o=json '.defaults.params // {}' "$MATRIX_FILE") +default_wait=$(yq '.defaults.wait_seconds // 60' "$MATRIX_FILE") configmap=$(yq ".cases[${case_index}].configmap // \"\"" "$MATRIX_FILE") case_params=$(yq -o=json ".cases[${case_index}].params // {}" "$MATRIX_FILE") +wait_seconds=$(yq ".cases[${case_index}].wait_seconds // ${default_wait}" "$MATRIX_FILE") wf_count=$(yq ".cases[${case_index}].workflows | length" "$MATRIX_FILE") echo "==========================================" @@ -63,8 +65,8 @@ if [[ -n "$configmap" ]]; then local_path="${REPO_ROOT}/${configmap}" echo "Applying configmap: ${local_path}" kubectl apply -f "${local_path}" - echo "Waiting 60s for ama-logs to detect configmap change..." - sleep 60 + echo "Waiting ${wait_seconds}s for ama-logs to detect configmap change..." + sleep "${wait_seconds}" fi # ── Run workflows ─────────────────────────────────────────── @@ -82,6 +84,8 @@ for (( w=0; w actual value) + val=$(echo "$val" | envsubst) config_flags+=" --config ${key}=${val}" done < <(echo "$merged" | jq -r 'keys[]') From bab93057b4dc1b042a8f5f841c5624ede9158efd Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Wed, 22 Apr 2026 10:08:34 -0700 Subject: [PATCH 23/26] group common workflow --- test/testkube/configmap-test-matrix.yaml | 29 ++++++++++++++++-------- test/testkube/run-matrix-tests.sh | 22 ++++++++++++++---- 2 files changed, 37 insertions(+), 14 deletions(-) diff --git a/test/testkube/configmap-test-matrix.yaml b/test/testkube/configmap-test-matrix.yaml index ea745f9b2..df0366437 100644 --- a/test/testkube/configmap-test-matrix.yaml +++ b/test/testkube/configmap-test-matrix.yaml @@ -3,10 +3,11 @@ # Each case: apply a configmap, then run workflows with specified params. # # Schema: -# defaults.params — merged into every workflow (lowest priority) -# case-level params — merged into all workflows in that case (overrides defaults) -# workflow params — merged last (highest priority) -# configmap — path relative to repo root; kubectl apply -f then wait +# defaults.params — merged into every workflow (lowest priority) +# defaults. — reusable workflow groups, included via "- name: " +# case-level params — merged into all workflows in that case (overrides defaults) +# workflow params — merged last (highest priority) +# configmap — path relative to repo root; kubectl apply -f then wait # defaults.wait_seconds — global wait time after applying configmap (default: 60) # case-level wait_seconds — per-case override @@ -14,6 +15,16 @@ defaults: wait_seconds: 600 params: GOTOOLCHAIN: "auto" + common_workflows: + - name: querylogs + params: + AZURE_TENANT_ID: ${AZURE_TENANT_ID} + AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} + GENEVA_INTEGRATION: false + - name: containerstatus-linux + common_workflows_test_only: + - name: containerstatus-windows + cases: - name: process-metrics-enabled @@ -25,11 +36,8 @@ cases: EXPECTED_TELEGRAF_RS: "1" EXPECTED_TELEGRAF_PROMETHEUS: "1" EXPECTED_TELEGRAF_WINDOWS: "1" - - name: querylogs - params: - AZURE_TENANT_ID: ${AZURE_TENANT_ID} - AZURE_CLIENT_ID: ${AZURE_CLIENT_ID} - GENEVA_INTEGRATION: false + - name: common_workflows + - name: common_workflows_test_only - name: process-metrics-default configmap: kubernetes/container-azm-ms-agentconfig.yaml @@ -40,4 +48,5 @@ cases: EXPECTED_TELEGRAF_RS: "0" EXPECTED_TELEGRAF_PROMETHEUS: "0" EXPECTED_TELEGRAF_WINDOWS: "0" - - name: containerstatus-linux + - name: common_workflows + - name: common_workflows_test_only diff --git a/test/testkube/run-matrix-tests.sh b/test/testkube/run-matrix-tests.sh index bb102afd7..c00bbccfe 100644 --- a/test/testkube/run-matrix-tests.sh +++ b/test/testkube/run-matrix-tests.sh @@ -54,11 +54,23 @@ default_wait=$(yq '.defaults.wait_seconds // 60' "$MATRIX_FILE") configmap=$(yq ".cases[${case_index}].configmap // \"\"" "$MATRIX_FILE") case_params=$(yq -o=json ".cases[${case_index}].params // {}" "$MATRIX_FILE") wait_seconds=$(yq ".cases[${case_index}].wait_seconds // ${default_wait}" "$MATRIX_FILE") -wf_count=$(yq ".cases[${case_index}].workflows | length" "$MATRIX_FILE") + +# Expand workflow groups: any workflow name matching a key under "defaults" gets replaced +case_workflows=$(yq -o=json ".cases[${case_index}].workflows // []" "$MATRIX_FILE") +defaults_json=$(yq -o=json '.defaults // {}' "$MATRIX_FILE") +all_workflows=$(jq -n --argjson wfs "$case_workflows" --argjson defaults "$defaults_json" ' + [($wfs[] | if $defaults[.name] then $defaults[.name][] else . end)] +') +wf_count=$(echo "$all_workflows" | jq 'length') echo "==========================================" echo "Case: ${CASE_NAME}" echo "==========================================" +echo "Workflows to run (${wf_count}):" +for (( i=0; i Date: Thu, 23 Apr 2026 09:53:36 -0700 Subject: [PATCH 24/26] refactor configmap_test package --- .../configmap/count_telegraf_process_test.go | 73 +++++++ test/ginkgo-e2e/configmap/go.mod | 74 +++++++ test/ginkgo-e2e/configmap/go.sum | 194 ++++++++++++++++++ test/ginkgo-e2e/configmap/suite_test.go | 26 +++ test/ginkgo-e2e/utils/constants.go | 7 +- test/testkube/configmap-test-matrix.yaml | 4 +- test/testkube/testkube-test-crs.yaml | 4 +- 7 files changed, 375 insertions(+), 7 deletions(-) create mode 100644 test/ginkgo-e2e/configmap/count_telegraf_process_test.go create mode 100644 test/ginkgo-e2e/configmap/go.mod create mode 100644 test/ginkgo-e2e/configmap/go.sum create mode 100644 test/ginkgo-e2e/configmap/suite_test.go diff --git a/test/ginkgo-e2e/configmap/count_telegraf_process_test.go b/test/ginkgo-e2e/configmap/count_telegraf_process_test.go new file mode 100644 index 000000000..cdbc9ac3b --- /dev/null +++ b/test/ginkgo-e2e/configmap/count_telegraf_process_test.go @@ -0,0 +1,73 @@ +package configmap_test + +import ( + "fmt" + "os" + "strconv" + + "docker-provider/test/utils" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" +) + +// envInt reads an integer from an environment variable, returning defaultVal if unset or invalid. +func envInt(key string, defaultVal int) int { + v := os.Getenv(key) + if v == "" { + return defaultVal + } + n, err := strconv.Atoi(v) + if err != nil { + return defaultVal + } + return n +} + +var _ = Describe("Process count validation", Label(utils.CountTelegrafProcessLabel), func() { + var ( + expectedTelegrafDS int + expectedTelegrafRS int + expectedTelegrafPrometheus int + expectedTelegrafWindows int + ) + + BeforeEach(func() { + expectedTelegrafDS = envInt("EXPECTED_TELEGRAF_DS", 1) + expectedTelegrafRS = envInt("EXPECTED_TELEGRAF_RS", 0) + expectedTelegrafPrometheus = envInt("EXPECTED_TELEGRAF_PROMETHEUS", 0) + expectedTelegrafWindows = envInt("EXPECTED_TELEGRAF_WINDOWS", 0) + }) + + It("ama-logs DS has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent", "ama-logs", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafDS), + fmt.Sprintf("expected %d telegraf in ama-logs DS, got %d", expectedTelegrafDS, count)) + }) + + It("ama-logs-rs has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "rsName", "ama-logs-rs", "ama-logs", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafRS), + fmt.Sprintf("expected %d telegraf in ama-logs-rs, got %d", expectedTelegrafRS, count)) + }) + + It("ama-logs-prometheus has expected telegraf count", func() { + count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafPrometheus), + fmt.Sprintf("expected %d telegraf in ama-logs-prometheus, got %d", expectedTelegrafPrometheus, count)) + }) + + It("ama-logs-windows has expected telegraf count", func() { + count, err := utils.CountWindowsProcessInstances(K8sClient, Cfg, "kube-system", + "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf") + Expect(err).NotTo(HaveOccurred()) + Expect(count).To(Equal(expectedTelegrafWindows), + fmt.Sprintf("expected %d telegraf in ama-logs-windows, got %d", expectedTelegrafWindows, count)) + }) +}) diff --git a/test/ginkgo-e2e/configmap/go.mod b/test/ginkgo-e2e/configmap/go.mod new file mode 100644 index 000000000..82cc717dd --- /dev/null +++ b/test/ginkgo-e2e/configmap/go.mod @@ -0,0 +1,74 @@ +module docker-provider/test/configmap + +go 1.26.1 + +replace docker-provider/test/utils => ../utils + +require ( + docker-provider/test/utils v0.0.0 + github.com/onsi/ginkgo/v2 v2.27.2 + github.com/onsi/gomega v1.38.2 + k8s.io/client-go v0.35.3 +) + +require ( + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 // indirect + github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/ghodss/yaml v1.0.0 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-task/slim-sprig/v3 v3.0.0 // indirect + github.com/golang-jwt/jwt/v5 v5.2.2 // indirect + github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/kylelemons/godebug v1.1.0 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/moby/spdystream v0.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect + github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect + github.com/spf13/pflag v1.0.9 // indirect + github.com/x448/float16 v0.8.4 // indirect + go.yaml.in/yaml/v2 v2.4.3 // indirect + go.yaml.in/yaml/v3 v3.0.4 // indirect + golang.org/x/crypto v0.44.0 // indirect + golang.org/x/mod v0.29.0 // indirect + golang.org/x/net v0.47.0 // indirect + golang.org/x/oauth2 v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect + golang.org/x/time v0.9.0 // indirect + golang.org/x/tools v0.38.0 // indirect + google.golang.org/protobuf v1.36.8 // indirect + gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.35.3 // indirect + k8s.io/apimachinery v0.35.3 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect + sigs.k8s.io/yaml v1.6.0 // indirect +) diff --git a/test/ginkgo-e2e/configmap/go.sum b/test/ginkgo-e2e/configmap/go.sum new file mode 100644 index 000000000..1a4d6f2c2 --- /dev/null +++ b/test/ginkgo-e2e/configmap/go.sum @@ -0,0 +1,194 @@ +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= +github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= +github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 h1:l+LIDHsZkFBiipIKhOn3m5/2MX4bwNwHYWyNulPaTis= +github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0/go.mod h1:BjVVBLUiZ/qR2a4PAhjs8uGXNfStD0tSxgxCMfcVRT8= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= +github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4= +github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= +github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= +github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= +github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= +github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= +github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= +github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= +github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= +github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= +github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= +github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= +github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= +github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= +github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= +github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= +github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= +github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= +github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= +github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= +github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= +github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= +github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= +github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= +github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= +go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= +golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= +golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= +golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= +golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= +google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= +google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= +gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= +k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= +k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= +k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= +k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= +k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= +k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= +k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= +sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= +sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= +sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/test/ginkgo-e2e/configmap/suite_test.go b/test/ginkgo-e2e/configmap/suite_test.go new file mode 100644 index 000000000..254820ccd --- /dev/null +++ b/test/ginkgo-e2e/configmap/suite_test.go @@ -0,0 +1,26 @@ +package configmap_test + +import ( + "testing" + + "docker-provider/test/utils" + + . "github.com/onsi/ginkgo/v2" + . "github.com/onsi/gomega" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +var K8sClient *kubernetes.Clientset +var Cfg *rest.Config + +func TestConfigmap(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Configmap Test Suite") +} + +var _ = BeforeSuite(func() { + var err error + K8sClient, Cfg, err = utils.SetupKubernetesClient() + Expect(err).NotTo(HaveOccurred()) +}) diff --git a/test/ginkgo-e2e/utils/constants.go b/test/ginkgo-e2e/utils/constants.go index a5bb73f86..ca8a1e9f5 100644 --- a/test/ginkgo-e2e/utils/constants.go +++ b/test/ginkgo-e2e/utils/constants.go @@ -18,9 +18,10 @@ var ( ) const ( - WindowsLabel = "windows" - ARM64Label = "arm64" - FIPSLabel = "fips" + WindowsLabel = "windows" + ARM64Label = "arm64" + FIPSLabel = "fips" + CountTelegrafProcessLabel = "count-telegraf-process" // also referenced in testkube-test-crs.yaml // IntermittentErrorThreshold is the maximum number of occurrences allowed for expected intermittent errors IntermittentErrorThreshold = 10 diff --git a/test/testkube/configmap-test-matrix.yaml b/test/testkube/configmap-test-matrix.yaml index df0366437..89de232ac 100644 --- a/test/testkube/configmap-test-matrix.yaml +++ b/test/testkube/configmap-test-matrix.yaml @@ -30,7 +30,7 @@ cases: - name: process-metrics-enabled configmap: test/configmaps/config-tests/container-azm-ms-agentconfig-process-metrics-enabled.yaml workflows: - - name: countprocess + - name: count-telegraf-process params: EXPECTED_TELEGRAF_DS: "2" EXPECTED_TELEGRAF_RS: "1" @@ -42,7 +42,7 @@ cases: - name: process-metrics-default configmap: kubernetes/container-azm-ms-agentconfig.yaml workflows: - - name: countprocess + - name: count-telegraf-process params: EXPECTED_TELEGRAF_DS: "1" EXPECTED_TELEGRAF_RS: "0" diff --git a/test/testkube/testkube-test-crs.yaml b/test/testkube/testkube-test-crs.yaml index 67f14396e..ee2a038aa 100644 --- a/test/testkube/testkube-test-crs.yaml +++ b/test/testkube/testkube-test-crs.yaml @@ -156,7 +156,7 @@ spec: apiVersion: testworkflows.testkube.io/v1 kind: TestWorkflow metadata: - name: countprocess + name: count-telegraf-process namespace: testkube labels: test-type: ginkgo-test @@ -199,7 +199,7 @@ spec: value: "{{config.EXPECTED_TELEGRAF_WINDOWS}}" - name: GOTOOLCHAIN value: "{{config.GOTOOLCHAIN}}" - shell: ginkgo run -r ./countprocess + shell: ginkgo --label-filter="count-telegraf-process" ./configmap pod: nodeSelector: kubernetes.io/os: linux From d07661ece5bec49a1012b3a3f390abf5e9325041 Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Thu, 23 Apr 2026 10:00:00 -0700 Subject: [PATCH 25/26] clean up --- .../countprocess/countprocess_suite_test.go | 26 --- .../countprocess/countprocess_test.go | 73 ------- test/ginkgo-e2e/countprocess/go.mod | 74 ------- test/ginkgo-e2e/countprocess/go.sum | 194 ------------------ .../install-and-execute-testkube-tests.sh | 101 +-------- 5 files changed, 1 insertion(+), 467 deletions(-) delete mode 100644 test/ginkgo-e2e/countprocess/countprocess_suite_test.go delete mode 100644 test/ginkgo-e2e/countprocess/countprocess_test.go delete mode 100644 test/ginkgo-e2e/countprocess/go.mod delete mode 100644 test/ginkgo-e2e/countprocess/go.sum diff --git a/test/ginkgo-e2e/countprocess/countprocess_suite_test.go b/test/ginkgo-e2e/countprocess/countprocess_suite_test.go deleted file mode 100644 index 3a3208560..000000000 --- a/test/ginkgo-e2e/countprocess/countprocess_suite_test.go +++ /dev/null @@ -1,26 +0,0 @@ -package countprocess_test - -import ( - "testing" - - "docker-provider/test/utils" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -var K8sClient *kubernetes.Clientset -var Cfg *rest.Config - -func TestCountProcess(t *testing.T) { - RegisterFailHandler(Fail) - RunSpecs(t, "Count Process Test Suite") -} - -var _ = BeforeSuite(func() { - var err error - K8sClient, Cfg, err = utils.SetupKubernetesClient() - Expect(err).NotTo(HaveOccurred()) -}) diff --git a/test/ginkgo-e2e/countprocess/countprocess_test.go b/test/ginkgo-e2e/countprocess/countprocess_test.go deleted file mode 100644 index 6834d262f..000000000 --- a/test/ginkgo-e2e/countprocess/countprocess_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package countprocess_test - -import ( - "fmt" - "os" - "strconv" - - "docker-provider/test/utils" - - . "github.com/onsi/ginkgo/v2" - . "github.com/onsi/gomega" -) - -// envInt reads an integer from an environment variable, returning defaultVal if unset or invalid. -func envInt(key string, defaultVal int) int { - v := os.Getenv(key) - if v == "" { - return defaultVal - } - n, err := strconv.Atoi(v) - if err != nil { - return defaultVal - } - return n -} - -var _ = Describe("Process count validation", func() { - var ( - expectedTelegrafDS int - expectedTelegrafRS int - expectedTelegrafPrometheus int - expectedTelegrafWindows int - ) - - BeforeEach(func() { - expectedTelegrafDS = envInt("EXPECTED_TELEGRAF_DS", 1) - expectedTelegrafRS = envInt("EXPECTED_TELEGRAF_RS", 0) - expectedTelegrafPrometheus = envInt("EXPECTED_TELEGRAF_PROMETHEUS", 0) - expectedTelegrafWindows = envInt("EXPECTED_TELEGRAF_WINDOWS", 0) - }) - - It("ama-logs DS has expected telegraf count", func() { - count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", - "component", "ama-logs-agent", "ama-logs", "telegraf") - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedTelegrafDS), - fmt.Sprintf("expected %d telegraf in ama-logs DS, got %d", expectedTelegrafDS, count)) - }) - - It("ama-logs-rs has expected telegraf count", func() { - count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", - "rsName", "ama-logs-rs", "ama-logs", "telegraf") - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedTelegrafRS), - fmt.Sprintf("expected %d telegraf in ama-logs-rs, got %d", expectedTelegrafRS, count)) - }) - - It("ama-logs-prometheus has expected telegraf count", func() { - count, err := utils.CountProcessInstances(K8sClient, Cfg, "kube-system", - "component", "ama-logs-agent", "ama-logs-prometheus", "telegraf") - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedTelegrafPrometheus), - fmt.Sprintf("expected %d telegraf in ama-logs-prometheus, got %d", expectedTelegrafPrometheus, count)) - }) - - It("ama-logs-windows has expected telegraf count", func() { - count, err := utils.CountWindowsProcessInstances(K8sClient, Cfg, "kube-system", - "component", "ama-logs-agent-windows", "ama-logs-windows", "telegraf") - Expect(err).NotTo(HaveOccurred()) - Expect(count).To(Equal(expectedTelegrafWindows), - fmt.Sprintf("expected %d telegraf in ama-logs-windows, got %d", expectedTelegrafWindows, count)) - }) -}) diff --git a/test/ginkgo-e2e/countprocess/go.mod b/test/ginkgo-e2e/countprocess/go.mod deleted file mode 100644 index 794440de1..000000000 --- a/test/ginkgo-e2e/countprocess/go.mod +++ /dev/null @@ -1,74 +0,0 @@ -module docker-provider/test/countprocess - -go 1.26.1 - -replace docker-provider/test/utils => ../utils - -require ( - docker-provider/test/utils v0.0.0 - github.com/onsi/ginkgo/v2 v2.27.2 - github.com/onsi/gomega v1.38.2 - k8s.io/client-go v0.35.3 -) - -require ( - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 // indirect - github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect - github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 // indirect - github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect - github.com/ghodss/yaml v1.0.0 // indirect - github.com/go-logr/logr v1.4.3 // indirect - github.com/go-openapi/jsonpointer v0.21.0 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/swag v0.23.0 // indirect - github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - github.com/golang-jwt/jwt/v5 v5.2.2 // indirect - github.com/google/gnostic-models v0.7.0 // indirect - github.com/google/go-cmp v0.7.0 // indirect - github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect - github.com/google/uuid v1.6.0 // indirect - github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/kylelemons/godebug v1.1.0 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/moby/spdystream v0.5.0 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect - github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect - github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect - github.com/spf13/pflag v1.0.9 // indirect - github.com/x448/float16 v0.8.4 // indirect - go.yaml.in/yaml/v2 v2.4.3 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect - golang.org/x/crypto v0.44.0 // indirect - golang.org/x/mod v0.29.0 // indirect - golang.org/x/net v0.47.0 // indirect - golang.org/x/oauth2 v0.30.0 // indirect - golang.org/x/sync v0.18.0 // indirect - golang.org/x/sys v0.38.0 // indirect - golang.org/x/term v0.37.0 // indirect - golang.org/x/text v0.31.0 // indirect - golang.org/x/time v0.9.0 // indirect - golang.org/x/tools v0.38.0 // indirect - google.golang.org/protobuf v1.36.8 // indirect - gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect - gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.35.3 // indirect - k8s.io/apimachinery v0.35.3 // indirect - k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect - sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect - sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect - sigs.k8s.io/yaml v1.6.0 // indirect -) diff --git a/test/ginkgo-e2e/countprocess/go.sum b/test/ginkgo-e2e/countprocess/go.sum deleted file mode 100644 index 1a4d6f2c2..000000000 --- a/test/ginkgo-e2e/countprocess/go.sum +++ /dev/null @@ -1,194 +0,0 @@ -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0 h1:g0EZJwz7xkXQiZAI5xi9f3WWFYBlX1CPTrR+NDToRkQ= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.17.0/go.mod h1:XCW7KnZet0Opnr7HccfUw1PLc4CjHqpcaxW8DHklNkQ= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2 h1:F0gBpfdPLGsw+nsgk6aqqkZS1jiixa5WwFe3fk/T3Ys= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.2/go.mod h1:SqINnQ9lVVdRlyC8cd1lCI0SdX4n2paeABd2K8ggfnE= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2 h1:yz1bePFlP5Vws5+8ez6T3HWXPmwOK7Yvq8QxDBD3SKY= -github.com/Azure/azure-sdk-for-go/sdk/azidentity/cache v0.3.2/go.mod h1:Pa9ZNPuoNu/GztvBSKk9J1cDJW6vk/n0zLtV4mgd8N8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= -github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0 h1:l+LIDHsZkFBiipIKhOn3m5/2MX4bwNwHYWyNulPaTis= -github.com/Azure/azure-sdk-for-go/sdk/monitor/azquery v1.1.0/go.mod h1:BjVVBLUiZ/qR2a4PAhjs8uGXNfStD0tSxgxCMfcVRT8= -github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1 h1:WJTmL004Abzc5wDB5VtZG2PJk5ndYDgVacGqfirKxjM= -github.com/AzureAD/microsoft-authentication-extensions-for-go/cache v0.1.1/go.mod h1:tCcJZ0uHAmvjsVYzEFivsRTN00oz5BEsRgQHu5JZ9WE= -github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3 h1:H5xDQaE3XowWfhZRUpnfC+rGZMEVoSiji+b+/HFAPU4= -github.com/AzureAD/microsoft-authentication-library-for-go v1.3.3/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= -github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= -github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= -github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= -github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= -github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= -github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= -github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= -github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= -github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= -github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= -github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= -github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= -github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= -github.com/golang-jwt/jwt/v5 v5.2.2 h1:Rl4B7itRWVtYIHFrSNd7vhTiz9UpLdi6gZhZ3wEeDy8= -github.com/golang-jwt/jwt/v5 v5.2.2/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= -github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= -github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8= -github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= -github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= -github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo= -github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= -github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6 h1:IsMZxCuZqKuao2vNdfD82fjjgPLfyHLpR41Z88viRWs= -github.com/keybase/go-keychain v0.0.0-20231219164618-57a3676c3af6/go.mod h1:3VeWNIJaW+O5xpRQbPp0Ybqu1vJd/pm7s2F473HRrkw= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= -github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= -github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= -github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= -github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= -github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8= -github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= -github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/redis/go-redis/v9 v9.7.0 h1:HhLSs+B6O021gwzl+locl0zEDnyNkxMtf/Z3NNBMa9E= -github.com/redis/go-redis/v9 v9.7.0/go.mod h1:f6zhXITC7JUJIlPEiBOTXxJgPLdZcA93GewI7inzyWw= -github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= -github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= -github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY= -github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= -github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= -github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= -github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= -github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= -github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= -github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= -github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= -go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= -go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= -go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= -golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= -golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= -golang.org/x/mod v0.29.0 h1:HV8lRxZC4l2cr3Zq1LvtOsi/ThTgWnUk/y64QSs8GwA= -golang.org/x/mod v0.29.0/go.mod h1:NyhrlYXJ2H4eJiRy/WDBO6HMqZQ6q9nk4JzS3NuCK+w= -golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= -golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= -golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI= -golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU= -golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= -golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= -golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= -golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= -golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= -golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= -golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= -golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= -golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= -golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= -google.golang.org/protobuf v1.36.8 h1:xHScyCOEuuwZEc6UtSOvPbAT4zRh0xcNRYekJwfqyMc= -google.golang.org/protobuf v1.36.8/go.mod h1:fuxRtAxBytpl4zzqUh6/eyUujkJdNiuEkXntxiD/uRU= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo= -gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= -gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ= -k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4= -k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8= -k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns= -k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg= -k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c= -k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= -k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= -sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= -sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= -sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco= -sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= -sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= -sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/test/testkube/install-and-execute-testkube-tests.sh b/test/testkube/install-and-execute-testkube-tests.sh index 14593003a..75e52d9dd 100644 --- a/test/testkube/install-and-execute-testkube-tests.sh +++ b/test/testkube/install-and-execute-testkube-tests.sh @@ -1,13 +1,9 @@ #!/bin/bash -ConfigTestMode=false -ConfigMap="" -Workflows="" - for ARGUMENT in "$@" do KEY=$(echo $ARGUMENT | cut -f1 -d=) - VALUE=$(echo $ARGUMENT | cut -f2- -d=) + VALUE=$(echo $ARGUMENT | cut -f2 -d=) case "$KEY" in AzureClientId) AzureClientId=$VALUE ;; @@ -15,9 +11,6 @@ do TeamsWebhookUri) TeamsWebhookUri=$VALUE ;; LinuxTestsOnly) LinuxTestsOnly=$VALUE ;; GenevaIntegration) GenevaIntegration=$VALUE ;; - ConfigTestMode) ConfigTestMode=$VALUE ;; - ConfigMap) ConfigMap=$VALUE ;; - Workflows) Workflows=$VALUE ;; *) esac done @@ -25,98 +18,6 @@ done cluster="$(kubectl config current-context)" echo "Current cluster: $cluster" -# ============================================================ -# ConfigTest mode: apply configmap, wait, run a single workflow -# Assumes TestKube is already installed by the pipeline setup. -# ============================================================ -if [[ "$ConfigTestMode" == "true" ]]; then - echo "========== ConfigTest Mode ==========" - - if [[ -z "$ConfigMap" || -z "$Workflows" ]]; then - echo "Error: ConfigTestMode requires ConfigMap and Workflows parameters" - exit 1 - fi - - # Apply the configmap variant - echo "Applying configmap: ${ConfigMap}" - kubectl apply -f "${ConfigMap}" - - # Wait for ama-logs to detect the configmap change and restart - echo "Waiting 60s for ama-logs to detect configmap change..." - sleep 60 - - failed_workflows=() - successful_workflows=() - - # Parse workflows: "wf1:key=val,key=val|wf2:key=val|wf3:" - IFS='|' read -ra wf_entries <<< "$Workflows" - for entry in "${wf_entries[@]}"; do - wf_name="${entry%%:*}" - wf_config="${entry#*:}" - - # Build --config flags for this workflow - config_flags="--config GOTOOLCHAIN=auto" - if [[ -n "$wf_config" ]]; then - IFS=',' read -ra pairs <<< "$wf_config" - for pair in "${pairs[@]}"; do - config_flags+=" --config ${pair}" - done - fi - - echo "Running workflow: ${wf_name} with config: ${config_flags}" - kubectl testkube run testworkflow "${wf_name}" ${config_flags} --verbose - - echo "Waiting for execution to be created..." - sleep 5 - - execution_id=$(kubectl testkube get testworkflowexecution | grep -i "${wf_name}" | head -n 1 | awk '{print $1}') - echo "Execution ID: ${execution_id}" - - if [[ -z "${execution_id}" ]]; then - echo "Error: Could not find execution ID for ${wf_name}" - failed_workflows+=("${wf_name} (no execution ID)") - continue - fi - - kubectl testkube watch testworkflowexecution "${execution_id}" - - kubectl testkube get testworkflowexecution "${execution_id}" --output json > "testkube-results-${wf_name}.json" - - if ! jq empty "testkube-results-${wf_name}.json" 2>/dev/null; then - echo "Error: Failed to get valid JSON results for ${wf_name}" - cat "testkube-results-${wf_name}.json" - failed_workflows+=("${wf_name} (invalid JSON)") - continue - fi - - result_status=$(jq -r '.result.status' "testkube-results-${wf_name}.json") - if [[ "${result_status}" == "failed" ]]; then - echo "TestWorkflow FAILED: ${wf_name} (execution: ${execution_id})" - kubectl testkube get testworkflowexecution "${execution_id}" --logs-only - failed_workflows+=("${wf_name} (execution: ${execution_id})") - else - echo "TestWorkflow PASSED: ${wf_name} (execution: ${execution_id})" - successful_workflows+=("${wf_name} (execution: ${execution_id})") - fi - done - - echo "" - echo "========== ConfigTest Summary ==========" - if [[ ${#successful_workflows[@]} -gt 0 ]]; then - echo "Passed:" - for wf in "${successful_workflows[@]}"; do echo " - $wf"; done - fi - if [[ ${#failed_workflows[@]} -gt 0 ]]; then - echo "Failed:" - for wf in "${failed_workflows[@]}"; do echo " - $wf"; done - echo "========================================" - exit 1 - fi - echo "All workflows passed." - echo "========================================" - exit 0 -fi - # Remove stale CRDs that block Helm ownership stale_crds=( "testworkflowexecutions.testworkflows.testkube.io" From 06e1f756dcbd49aa097a66dd482c083a74d857ad Mon Sep 17 00:00:00 2001 From: zanejohnson-azure Date: Thu, 23 Apr 2026 10:02:22 -0700 Subject: [PATCH 26/26] rename script --- .pipelines/azure-pipeline-config-tests.yaml | 4 ++-- .../{run-matrix-tests.sh => run-configmap-test-case.sh} | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename test/testkube/{run-matrix-tests.sh => run-configmap-test-case.sh} (100%) diff --git a/.pipelines/azure-pipeline-config-tests.yaml b/.pipelines/azure-pipeline-config-tests.yaml index 3bf9880a4..1661b836c 100644 --- a/.pipelines/azure-pipeline-config-tests.yaml +++ b/.pipelines/azure-pipeline-config-tests.yaml @@ -203,8 +203,8 @@ stages: # === Run test cases (one step per case) === - ${{ each caseName in parameters.cases }}: - bash: | - chmod +x ./run-matrix-tests.sh - ./run-matrix-tests.sh \ + chmod +x ./run-configmap-test-case.sh + ./run-configmap-test-case.sh \ --case "${{ caseName }}" \ --repo-root "$(Build.SourcesDirectory)" workingDirectory: $(Build.SourcesDirectory)/test/testkube diff --git a/test/testkube/run-matrix-tests.sh b/test/testkube/run-configmap-test-case.sh similarity index 100% rename from test/testkube/run-matrix-tests.sh rename to test/testkube/run-configmap-test-case.sh