diff --git a/test/e2e/common/validate-metric.go b/test/e2e/common/validate-metric.go new file mode 100755 index 0000000000..49c0a2e7be --- /dev/null +++ b/test/e2e/common/validate-metric.go @@ -0,0 +1,52 @@ +package common + +import ( + "errors" + "fmt" + "log" + + prom "github.com/microsoft/retina/test/e2e/framework/prometheus" +) + +var ( + ErrMetricFound = errors.New("unexpected metric found") +) + +type ValidateMetric struct { + ForwardedPort string + MetricName string + ValidMetrics []map[string]string + ExpectMetric bool +} + +func (v *ValidateMetric) Run() error { + promAddress := fmt.Sprintf("http://localhost:%s/metrics", v.ForwardedPort) + + for _, validMetric := range v.ValidMetrics { + err := prom.CheckMetric(promAddress, v.MetricName, validMetric) + if err != nil { + // If we expect the metric not to be found, return nil if it's not found. + if !v.ExpectMetric && errors.Is(err, prom.ErrNoMetricFound) { + log.Printf("metric %s not found, as expected\n", v.MetricName) + return nil + } + return fmt.Errorf("failed to verify prometheus metrics: %w", err) + } + + // if we expect the metric not to be found, return an error if it is found + if !v.ExpectMetric { + return fmt.Errorf("did not expect to find metric %s matching %+v: %w", v.MetricName, validMetric, ErrMetricFound) + } + + log.Printf("found metric %s matching %+v\n", v.MetricName, validMetric) + } + return nil +} + +func (v *ValidateMetric) Prevalidate() error { + return nil +} + +func (v *ValidateMetric) Stop() error { + return nil +} diff --git a/test/e2e/framework/constants/hubble.go b/test/e2e/framework/constants/hubble.go new file mode 100755 index 0000000000..0efb06b151 --- /dev/null +++ b/test/e2e/framework/constants/hubble.go @@ -0,0 +1,31 @@ +package constants + +const ( + // Metrics Port + HubbleMetricsPort = "9965" + + // MetricsName + HubbleDNSQueryMetricName = "hubble_dns_queries_total" + HubbleDNSResponseMetricName = "hubble_dns_responses_total" + HubbleFlowMetricName = "hubble_flows_processed_total" + HubbleDropMetricName = "hubble_drop_total" + HubbleTCPFlagsMetricName = "hubble_tcp_flags_total" + + // Labels + HubbleDestinationLabel = "destination" + HubbleSourceLabel = "source" + HubbleIPsRetunedLabel = "ips_returned" + HubbleQTypesLabel = "qtypes" + HubbleRCodeLabel = "rcode" + HubbleQueryLabel = "query" + + HubbleProtocolLabel = "protocol" + HubbleReasonLabel = "reason" + + HubbleSubtypeLabel = "subtype" + HubbleTypeLabel = "type" + HubbleVerdictLabel = "verdict" + + HubbleFamilyLabel = "family" + HubbleFlagLabel = "flag" +) diff --git a/test/e2e/framework/constants/networking.go b/test/e2e/framework/constants/networking.go new file mode 100755 index 0000000000..4b44570eff --- /dev/null +++ b/test/e2e/framework/constants/networking.go @@ -0,0 +1,13 @@ +package constants + +const ( + TCP = "TCP" + UDP = "UDP" + IPV4 = "IPv4" + IPTableRuleDrop = "IPTABLE_RULE_DROP" + SYN = "SYN" + SYNACK = "SYN-ACK" + ACK = "ACK" + FIN = "FIN" + RST = "RST" +) diff --git a/test/e2e/framework/kubernetes/install-hubble-helm.go b/test/e2e/framework/kubernetes/install-hubble-helm.go index 5e225d08e6..4cf7f32351 100644 --- a/test/e2e/framework/kubernetes/install-hubble-helm.go +++ b/test/e2e/framework/kubernetes/install-hubble-helm.go @@ -23,7 +23,7 @@ const ( HubbleRelayApp = "hubble-relay" ) -type ValidateHubbleStep struct { +type InstallHubbleHelmChart struct { Namespace string ReleaseName string KubeConfigFilePath string @@ -31,7 +31,7 @@ type ValidateHubbleStep struct { TagEnv string } -func (v *ValidateHubbleStep) Run() error { +func (v *InstallHubbleHelmChart) Run() error { ctx, cancel := context.WithTimeout(context.Background(), defaultTimeoutSeconds*time.Second) defer cancel() @@ -146,10 +146,10 @@ func (v *ValidateHubbleStep) Run() error { return nil } -func (v *ValidateHubbleStep) Prevalidate() error { +func (v *InstallHubbleHelmChart) Prevalidate() error { return nil } -func (v *ValidateHubbleStep) Stop() error { +func (v *InstallHubbleHelmChart) Stop() error { return nil } diff --git a/test/e2e/framework/scaletest/validate-options.go b/test/e2e/framework/scaletest/validate-options.go index 0dafdd2b06..588bdc993b 100644 --- a/test/e2e/framework/scaletest/validate-options.go +++ b/test/e2e/framework/scaletest/validate-options.go @@ -37,7 +37,6 @@ func (po *ValidateAndPrintOptions) Prevalidate() error { // Returning an error will cause the test to fail func (po *ValidateAndPrintOptions) Run() error { - log.Printf("Starting to scale with folowing options: %+v", po.Options) return nil diff --git a/test/e2e/jobs/jobs.go b/test/e2e/jobs/jobs.go index 81b64118a0..80901f10a7 100644 --- a/test/e2e/jobs/jobs.go +++ b/test/e2e/jobs/jobs.go @@ -6,9 +6,12 @@ import ( "github.com/microsoft/retina/test/e2e/framework/generic" "github.com/microsoft/retina/test/e2e/framework/kubernetes" "github.com/microsoft/retina/test/e2e/framework/types" - "github.com/microsoft/retina/test/e2e/hubble" "github.com/microsoft/retina/test/e2e/scenarios/dns" "github.com/microsoft/retina/test/e2e/scenarios/drop" + hubble_dns "github.com/microsoft/retina/test/e2e/scenarios/hubble/dns" + hubble_flow "github.com/microsoft/retina/test/e2e/scenarios/hubble/flow" + hubble_service "github.com/microsoft/retina/test/e2e/scenarios/hubble/service" + hubble_tcp "github.com/microsoft/retina/test/e2e/scenarios/hubble/tcp" "github.com/microsoft/retina/test/e2e/scenarios/latency" tcp "github.com/microsoft/retina/test/e2e/scenarios/tcp" "github.com/microsoft/retina/test/e2e/scenarios/windows" @@ -242,10 +245,10 @@ func UpgradeAndTestRetinaAdvancedMetrics(kubeConfigFilePath, chartPath, valuesFi return job } -func ValidateHubble(kubeConfigFilePath, chartPath string, testPodNamespace string) *types.Job { +func InstallAndTestHubbleMetrics(kubeConfigFilePath, chartPath string) *types.Job { job := types.NewJob("Validate Hubble") - job.AddStep(&kubernetes.ValidateHubbleStep{ + job.AddStep(&kubernetes.InstallHubbleHelmChart{ Namespace: common.KubeSystemNamespace, ReleaseName: "retina", KubeConfigFilePath: kubeConfigFilePath, @@ -253,9 +256,18 @@ func ValidateHubble(kubeConfigFilePath, chartPath string, testPodNamespace strin TagEnv: generic.DefaultTagEnv, }, nil) - job.AddScenario(hubble.ValidateHubbleRelayService()) + hubbleScrenarios := []*types.Scenario{ + hubble_dns.ValidateDNSMetric(), + hubble_flow.ValidateFlowMetric(), + // hubble_drop.ValidateDropMetric(), TODO Needs to investigate why drop metrics are not present. + hubble_tcp.ValidateTCPMetric(), + hubble_service.ValidateHubbleRelayService(), + hubble_service.ValidateHubbleUIService(kubeConfigFilePath), + } - job.AddScenario(hubble.ValidateHubbleUIService(kubeConfigFilePath)) + for _, scenario := range hubbleScrenarios { + job.AddScenario(scenario) + } job.AddStep(&kubernetes.EnsureStableComponent{ PodNamespace: common.KubeSystemNamespace, diff --git a/test/e2e/retina_e2e_test.go b/test/e2e/retina_e2e_test.go index 9cf7c58315..25bccaf78b 100644 --- a/test/e2e/retina_e2e_test.go +++ b/test/e2e/retina_e2e_test.go @@ -54,12 +54,7 @@ func TestE2ERetina(t *testing.T) { ) advanceMetricsE2E.Run(ctx) - // Install and test Hubble basic metrics - validatehubble := types.NewRunner(t, - jobs.ValidateHubble( - common.KubeConfigFilePath(rootDir), - hubblechartPath, - common.TestPodNamespace), - ) - validatehubble.Run(ctx) + // Install and test Hubble metrics + hubbleMetricsE2E := types.NewRunner(t, jobs.InstallAndTestHubbleMetrics(kubeConfigFilePath, hubblechartPath, common.TestPodNamespace)) + hubbleMetricsE2E.Run(ctx) } diff --git a/test/e2e/scenarios/hubble/dns/labels.go b/test/e2e/scenarios/hubble/dns/labels.go new file mode 100755 index 0000000000..018dd18c4d --- /dev/null +++ b/test/e2e/scenarios/hubble/dns/labels.go @@ -0,0 +1,26 @@ +package dns + +import ( + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" +) + +var ( + podName = "agnhost-dns-0" + validDNSQueryMetricLabels = map[string]string{ + constants.HubbleDestinationLabel: "", + constants.HubbleSourceLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleIPsRetunedLabel: "0", + constants.HubbleQTypesLabel: "A", + constants.HubbleRCodeLabel: "", + constants.HubbleQueryLabel: "one.one.one.one.", + } + validDNSResponseMetricLabels = map[string]string{ + constants.HubbleDestinationLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleSourceLabel: "", + constants.HubbleIPsRetunedLabel: "2", + constants.HubbleQTypesLabel: "A", + constants.HubbleRCodeLabel: "No Error", + constants.HubbleQueryLabel: "one.one.one.one.", + } +) diff --git a/test/e2e/scenarios/hubble/dns/scenario.go b/test/e2e/scenarios/hubble/dns/scenario.go new file mode 100755 index 0000000000..632dabacee --- /dev/null +++ b/test/e2e/scenarios/hubble/dns/scenario.go @@ -0,0 +1,85 @@ +package dns + +import ( + "time" + + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" + "github.com/microsoft/retina/test/e2e/framework/kubernetes" + "github.com/microsoft/retina/test/e2e/framework/types" +) + +const ( + sleepDelay = 5 * time.Second +) + +func ValidateDNSMetric() *types.Scenario { + name := "DNS Metrics" + agnhostName := "agnhost-dns" + podName := agnhostName + "-0" + steps := []*types.StepWrapper{ + { + Step: &kubernetes.CreateAgnhostStatefulSet{ + AgnhostName: agnhostName, + AgnhostNamespace: common.TestPodNamespace, + }, + }, + { + Step: &kubernetes.PortForward{ + LabelSelector: "k8s-app=retina", + LocalPort: constants.HubbleMetricsPort, + RemotePort: constants.HubbleMetricsPort, + Namespace: common.KubeSystemNamespace, + Endpoint: "metrics", + OptionalLabelAffinity: "app=" + agnhostName, // port forward hubble metrics to a pod on a node that also has this pod with this label, assuming same namespace + }, + Opts: &types.StepOptions{ + RunInBackgroundWithID: "hubble-dns-port-forward", + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "nslookup -type=a one.one.one.one", + }, + Opts: &types.StepOptions{ + ExpectError: false, + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Sleep{ + Duration: sleepDelay, + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleDNSQueryMetricName, + ValidMetrics: []map[string]string{validDNSQueryMetricLabels}, + ExpectMetric: true, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleDNSResponseMetricName, + ValidMetrics: []map[string]string{validDNSResponseMetricLabels}, + ExpectMetric: true, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Stop{ + BackgroundID: "hubble-dns-port-forward", + }, + }, + } + return types.NewScenario(name, steps...) +} diff --git a/test/e2e/scenarios/hubble/drop/labels.go b/test/e2e/scenarios/hubble/drop/labels.go new file mode 100755 index 0000000000..ad330abe25 --- /dev/null +++ b/test/e2e/scenarios/hubble/drop/labels.go @@ -0,0 +1,16 @@ +package drop + +import ( + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" +) + +var ( + podName = "agnhost-drop-0" + validHubbleDropMetricLabels = map[string]string{ + constants.HubbleSourceLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleDestinationLabel: "", + constants.HubbleProtocolLabel: constants.UDP, + constants.HubbleReasonLabel: "POLICY_DENIED", + } +) diff --git a/test/e2e/scenarios/hubble/drop/scenario.go b/test/e2e/scenarios/hubble/drop/scenario.go new file mode 100755 index 0000000000..e820323e3d --- /dev/null +++ b/test/e2e/scenarios/hubble/drop/scenario.go @@ -0,0 +1,110 @@ +package drop + +import ( + "time" + + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" + "github.com/microsoft/retina/test/e2e/framework/kubernetes" + "github.com/microsoft/retina/test/e2e/framework/types" +) + +const ( + sleepDelay = 5 * time.Second +) + +func ValidateDropMetric() *types.Scenario { + name := "Drop Metrics" + agnhostName := "agnhost-drop" + podName := agnhostName + "-0" + steps := []*types.StepWrapper{ + { + Step: &kubernetes.CreateDenyAllNetworkPolicy{ + NetworkPolicyNamespace: common.KubeSystemNamespace, + DenyAllLabelSelector: "app=" + agnhostName, + }, + }, + { + Step: &kubernetes.CreateAgnhostStatefulSet{ + AgnhostName: agnhostName, + AgnhostNamespace: common.TestPodNamespace, + }, + }, + { + Step: &kubernetes.PortForward{ + LabelSelector: "k8s-app=retina", + LocalPort: constants.HubbleMetricsPort, + RemotePort: constants.HubbleMetricsPort, + Namespace: common.KubeSystemNamespace, + Endpoint: "metrics", + OptionalLabelAffinity: "app=" + agnhostName, // port forward hubble metrics to a pod on a node that also has this pod with this label, assuming same namespace + }, + Opts: &types.StepOptions{ + RunInBackgroundWithID: "hubble-drop-port-forward", + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleDropMetricName, + ValidMetrics: []map[string]string{validHubbleDropMetricLabels}, + ExpectMetric: false, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + ExpectError: true, + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Sleep{ + Duration: sleepDelay, + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + ExpectError: true, + SkipSavingParametersToJob: true, + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleDropMetricName, + ValidMetrics: []map[string]string{validHubbleDropMetricLabels}, + ExpectMetric: true, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Stop{ + BackgroundID: "hubble-drop-port-forward", + }, + }, + { + Step: &kubernetes.DeleteKubernetesResource{ + ResourceType: kubernetes.TypeString(kubernetes.NetworkPolicy), + ResourceName: "deny-all", + ResourceNamespace: common.KubeSystemNamespace, + }, + }, + } + return types.NewScenario(name, steps...) +} diff --git a/test/e2e/scenarios/hubble/flow/labels.go b/test/e2e/scenarios/hubble/flow/labels.go new file mode 100755 index 0000000000..6b2376a7eb --- /dev/null +++ b/test/e2e/scenarios/hubble/flow/labels.go @@ -0,0 +1,50 @@ +package flow + +import ( + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" +) + +var ( + podName = "agnhost-flow-0" + validHubbleFlowLabelsToStack = map[string]string{ + constants.HubbleSourceLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleDestinationLabel: "", + constants.HubbleProtocolLabel: constants.UDP, + constants.HubbleSubtypeLabel: "to-stack", + constants.HubbleTypeLabel: "Trace", + constants.HubbleVerdictLabel: "FORWARDED", + } + validHubbleFlowLabelsToNetwork = map[string]string{ + constants.HubbleSourceLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleDestinationLabel: "", + constants.HubbleProtocolLabel: constants.UDP, + constants.HubbleSubtypeLabel: "to-network", + constants.HubbleTypeLabel: "Trace", + constants.HubbleVerdictLabel: "FORWARDED", + } + validHubbleFlowLabelsFromNetwork = map[string]string{ + constants.HubbleSourceLabel: "", + constants.HubbleDestinationLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleProtocolLabel: constants.UDP, + constants.HubbleSubtypeLabel: "from-network", + constants.HubbleTypeLabel: "Trace", + constants.HubbleVerdictLabel: "FORWARDED", + } + validHubbleFlowLabelsToEndpoint = map[string]string{ + constants.HubbleSourceLabel: "", + constants.HubbleDestinationLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleProtocolLabel: constants.TCP, + constants.HubbleSubtypeLabel: "to-endpoint", + constants.HubbleTypeLabel: "Trace", + constants.HubbleVerdictLabel: "FORWARDED", + } + + validHubbleFlowMetricsLabels = []map[string]string{ + validHubbleFlowLabelsToStack, + // TODO: Needs to further investigate why these labels are not being generated + // validHubbleFlowLabelsToNetwork, + // validHubbleFlowLabelsFromNetwork, + validHubbleFlowLabelsToEndpoint, + } +) diff --git a/test/e2e/scenarios/hubble/flow/scenario.go b/test/e2e/scenarios/hubble/flow/scenario.go new file mode 100755 index 0000000000..b9bacf3623 --- /dev/null +++ b/test/e2e/scenarios/hubble/flow/scenario.go @@ -0,0 +1,91 @@ +package flow + +import ( + "time" + + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" + "github.com/microsoft/retina/test/e2e/framework/kubernetes" + "github.com/microsoft/retina/test/e2e/framework/types" +) + +const ( + sleepDelay = 5 * time.Second +) + +func ValidateFlowMetric() *types.Scenario { + name := "Flow Metrics" + agnhostName := "agnhost-flow" + podName := agnhostName + "-0" + steps := []*types.StepWrapper{ + { + Step: &kubernetes.CreateKapingerDeployment{ + KapingerNamespace: common.KubeSystemNamespace, + KapingerReplicas: "1", + }, + }, + { + Step: &kubernetes.CreateAgnhostStatefulSet{ + AgnhostName: agnhostName, + AgnhostNamespace: common.TestPodNamespace, + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Sleep{ + Duration: sleepDelay, + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &kubernetes.PortForward{ + LabelSelector: "k8s-app=retina", + LocalPort: constants.HubbleMetricsPort, + RemotePort: constants.HubbleMetricsPort, + Namespace: common.KubeSystemNamespace, + Endpoint: "metrics", + OptionalLabelAffinity: "app=" + agnhostName, // port forward to a pod on a node that also has this pod with this label, assuming same namespace + }, + Opts: &types.StepOptions{ + RunInBackgroundWithID: "hubble-flow-port-forward", + SkipSavingParametersToJob: true, + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleFlowMetricName, + ValidMetrics: validHubbleFlowMetricsLabels, + ExpectMetric: true, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Stop{ + BackgroundID: "hubble-flow-port-forward", + }, + }, + } + + return types.NewScenario(name, steps...) +} diff --git a/test/e2e/hubble/scenario.go b/test/e2e/scenarios/hubble/service/scenario.go similarity index 98% rename from test/e2e/hubble/scenario.go rename to test/e2e/scenarios/hubble/service/scenario.go index 92de650b32..59dd15da99 100644 --- a/test/e2e/hubble/scenario.go +++ b/test/e2e/scenarios/hubble/service/scenario.go @@ -1,4 +1,4 @@ -package hubble +package services import ( "net/http" diff --git a/test/e2e/scenarios/hubble/tcp/labels.go b/test/e2e/scenarios/hubble/tcp/labels.go new file mode 100755 index 0000000000..e65d2cb184 --- /dev/null +++ b/test/e2e/scenarios/hubble/tcp/labels.go @@ -0,0 +1,34 @@ +package tcp + +import ( + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" +) + +var ( + podName = "agnhost-tcp-0" + validHubbleTCPSYNFlag = map[string]string{ + constants.HubbleSourceLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleDestinationLabel: "", + constants.HubbleFamilyLabel: constants.IPV4, + constants.HubbleFlagLabel: constants.SYN, + } + validHubbleTCPSYNACKFlag = map[string]string{ + constants.HubbleSourceLabel: "", + constants.HubbleDestinationLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleFamilyLabel: constants.IPV4, + constants.HubbleFlagLabel: constants.SYNACK, + } + validHubbleTCPFINFlag = map[string]string{ + constants.HubbleSourceLabel: "", + constants.HubbleDestinationLabel: common.TestPodNamespace + "/" + podName, + constants.HubbleFamilyLabel: constants.IPV4, + constants.HubbleFlagLabel: constants.FIN, + } + + validHubbleTCPMetricsLabels = []map[string]string{ + validHubbleTCPSYNFlag, + // validHubbleTCPSYNACKFlag, TODO: Needs to further investigate why these labels are not being generated + validHubbleTCPFINFlag, + } +) diff --git a/test/e2e/scenarios/hubble/tcp/scenario.go b/test/e2e/scenarios/hubble/tcp/scenario.go new file mode 100755 index 0000000000..9023f622df --- /dev/null +++ b/test/e2e/scenarios/hubble/tcp/scenario.go @@ -0,0 +1,91 @@ +package tcp + +import ( + "time" + + "github.com/microsoft/retina/test/e2e/common" + "github.com/microsoft/retina/test/e2e/framework/constants" + "github.com/microsoft/retina/test/e2e/framework/kubernetes" + "github.com/microsoft/retina/test/e2e/framework/types" +) + +const ( + sleepDelay = 5 * time.Second +) + +func ValidateTCPMetric() *types.Scenario { + name := "TCP Flags Metrics" + agnhostName := "agnhost-tcp" + podName := agnhostName + "-0" + steps := []*types.StepWrapper{ + { + Step: &kubernetes.CreateKapingerDeployment{ + KapingerNamespace: common.KubeSystemNamespace, + KapingerReplicas: "1", + }, + }, + { + Step: &kubernetes.CreateAgnhostStatefulSet{ + AgnhostName: agnhostName, + AgnhostNamespace: common.TestPodNamespace, + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Sleep{ + Duration: sleepDelay, + }, + }, + { + Step: &kubernetes.ExecInPod{ + PodName: podName, + PodNamespace: common.TestPodNamespace, + Command: "curl -s -m 5 bing.com", + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &kubernetes.PortForward{ + LabelSelector: "k8s-app=retina", + LocalPort: constants.HubbleMetricsPort, + RemotePort: constants.HubbleMetricsPort, + Namespace: common.KubeSystemNamespace, + Endpoint: "metrics", + OptionalLabelAffinity: "app=" + agnhostName, // port forward to a pod on a node that also has this pod with this label, assuming same namespace + }, + Opts: &types.StepOptions{ + RunInBackgroundWithID: "hubble-tcp-port-forward", + SkipSavingParametersToJob: true, + }, + }, + { + Step: &common.ValidateMetric{ + ForwardedPort: constants.HubbleMetricsPort, + MetricName: constants.HubbleTCPFlagsMetricName, + ValidMetrics: validHubbleTCPMetricsLabels, + ExpectMetric: true, + }, + Opts: &types.StepOptions{ + SkipSavingParametersToJob: true, + }, + }, + { + Step: &types.Stop{ + BackgroundID: "hubble-tcp-port-forward", + }, + }, + } + + return types.NewScenario(name, steps...) +}