Skip to content

Commit

Permalink
Add integration test for stats filter and metatdata exchange (istio#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
bianpengyuan authored and istio-testing committed Sep 12, 2019
1 parent 2149622 commit 5112e15
Show file tree
Hide file tree
Showing 3 changed files with 289 additions and 0 deletions.
199 changes: 199 additions & 0 deletions tests/integration/telemetry/stats/prometheus/stats_filter_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// Copyright 2019 Istio Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package promtheus

import (
"fmt"
"testing"
"time"

"istio.io/istio/pkg/test/framework"
"istio.io/istio/pkg/test/framework/components/bookinfo"
"istio.io/istio/pkg/test/framework/components/environment"
"istio.io/istio/pkg/test/framework/components/galley"
"istio.io/istio/pkg/test/framework/components/ingress"
"istio.io/istio/pkg/test/framework/components/istio"
"istio.io/istio/pkg/test/framework/components/namespace"
"istio.io/istio/pkg/test/framework/components/prometheus"
"istio.io/istio/pkg/test/framework/resource"
"istio.io/istio/pkg/test/util/file"
"istio.io/istio/pkg/test/util/retry"
util "istio.io/istio/tests/integration/mixer"
)

const (
statsFilterConfig = "testdata/stats_filter.yaml"
metadataExchangeFilterConfig = "testdata/metadata_exchange_filter.yaml"
)

var (
ist istio.Instance
bookinfoNsInst namespace.Instance
galInst galley.Instance
ingInst ingress.Instance
promInst prometheus.Instance
)

func getIstioInstance() *istio.Instance {
return &ist
}

func getBookinfoNamespaceInstance() namespace.Instance {
return bookinfoNsInst
}

func getIngressInstance() ingress.Instance {
return ingInst
}

func getPromInstance() prometheus.Instance {
return promInst
}

func queryPrometheus(t *testing.T, query string) error {
promInst := getPromInstance()
t.Logf("query prometheus with: %v", query)
val, err := promInst.WaitForQuiesce(query)
if err != nil {
return err
}
got, err := promInst.Sum(val, nil)
if err != nil {
t.Logf("value: %s", val.String())
return fmt.Errorf("could not find metric value: %v", err)
}
t.Logf("get value %v", got)
return nil
}

func buildQuery() (sourceQuery, destinationQuery string) {
bookinfoNsInst := getBookinfoNamespaceInstance()
sourceQuery = `istio_requests_total{reporter="source",`
destinationQuery = `istio_requests_total{reporter="destination",`
labels := map[string]string{
"request_protocol": "http",
"response_code": "200",
"destination_app": "reviews",
"destination_version": "v1",
"destination_service": "reviews:9080",
"destination_service_name": "reviews-v1",
"destination_workload_namespace": bookinfoNsInst.Name(),
"destination_service_namespace": bookinfoNsInst.Name(),
"source_app": "productpage",
"source_version": "v1",
"source_workload": "productpage-v1",
"source_workload_namespace": bookinfoNsInst.Name(),
}
for k, v := range labels {
sourceQuery += fmt.Sprintf(`%s=%q,`, k, v)
destinationQuery += fmt.Sprintf(`%s=%q,`, k, v)
}
sourceQuery += "}"
destinationQuery += "}"
return
}

// TestStatsFilter verifies the stats filter could emit expected client and server side metrics.
// This test focuses on stats filter and metadata exchange filter could work coherently with
// proxy bootstrap config. To avoid flake, it does not verify correctness of metrics, which
// should be covered by integration test in proxy repo.
func TestStatsFilter(t *testing.T) {
framework.NewTest(t).
RequiresEnvironment(environment.Kube).
Run(func(ctx framework.TestContext) {
ingress := getIngressInstance()
addr := ingress.HTTPAddress()
url := fmt.Sprintf("http://%s/productpage", addr.String())
sourceQuery, destinationQuery := buildQuery()
retry.UntilSuccessOrFail(t, func() error {
util.SendTraffic(ingress, t, "Sending traffic", url, "", 200)
// Query client side metrics
if err := queryPrometheus(t, sourceQuery); err != nil {
return err
}
if err := queryPrometheus(t, destinationQuery); err != nil {
return err
}
return nil
}, retry.Delay(3*time.Second), retry.Timeout(80*time.Second))
})
}

func TestMain(m *testing.M) {
framework.NewSuite("stats_filter_test", m).
RequireEnvironment(environment.Kube).
SetupOnEnv(environment.Kube, istio.Setup(getIstioInstance(), setupConfig)).
Setup(testSetup).
Run()
}

func setupConfig(cfg *istio.Config) {
if cfg == nil {
return
}
// disable telemetry and mixer filter
cfg.Values["global.disablePolicyChecks"] = "true"
cfg.Values["global.MixerCheckServer"] = ""
cfg.Values["global.MixerReportServer"] = ""
cfg.Values["mixer.telemetry.enabled"] = "false"
}

func testSetup(ctx resource.Context) (err error) {
galInst, err = galley.New(ctx, galley.Config{})
if err != nil {
return
}
bookinfoNsInst, err = namespace.New(ctx, namespace.Config{
Prefix: "istio-bookinfo",
Inject: true,
})
if err != nil {
return
}
if _, err = bookinfo.Deploy(ctx, bookinfo.Config{Namespace: bookinfoNsInst, Cfg: bookinfo.BookInfo}); err != nil {
return
}
ingInst, err = ingress.New(ctx, ingress.Config{Istio: ist})
if err != nil {
return
}
promInst, err = prometheus.New(ctx)
if err != nil {
return
}
bookingfoGatewayFile, err := bookinfo.NetworkingBookinfoGateway.LoadGatewayFileWithNamespace(bookinfoNsInst.Name())
if err != nil {
return
}
// Apply metadata exchange filter and stats filter.
statsFilterFile, err := file.AsString(statsFilterConfig)
if err != nil {
return
}
exchangeFilterFile, err := file.AsString(metadataExchangeFilterConfig)
if err != nil {
return
}
err = galInst.ApplyConfig(
bookinfoNsInst,
bookingfoGatewayFile,
statsFilterFile,
exchangeFilterFile,
)
if err != nil {
return
}
return nil
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: metadata-exchange
spec:
filters:
- filterConfig:
configuration: envoy.wasm.metadata_exchange
vm_config:
code:
inline_string: envoy.wasm.metadata_exchange
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: SIDECAR_INBOUND
- filterConfig:
configuration: envoy.wasm.metadata_exchange
vm_config:
code:
inline_string: envoy.wasm.metadata_exchange
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: SIDECAR_OUTBOUND
- filterConfig:
configuration: envoy.wasm.metadata_exchange
vm_config:
code:
inline_string: envoy.wasm.metadata_exchange
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: GATEWAY
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: stats-filter
spec:
filters:
- filterConfig:
configuration: |
{
"debug": "false",
"stat_prefix": "istio",
}
vm_config:
code:
inline_string: envoy.wasm.stats
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: GATEWAY
- filterConfig:
configuration: |
{
"debug": "false",
"stat_prefix": "istio",
}
vm_config:
code:
inline_string: envoy.wasm.stats
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: SIDECAR_INBOUND
- filterConfig:
configuration: |
{
"debug": "false",
"stat_prefix": "istio",
}
vm_config:
code:
inline_string: envoy.wasm.stats
vm: envoy.wasm.vm.null
filterName: envoy.wasm
filterType: HTTP
listenerMatch:
listenerProtocol: HTTP
listenerType: SIDECAR_OUTBOUND

0 comments on commit 5112e15

Please sign in to comment.