From 1b4d2b13283006d118d109bcb40bb189a5daf4c2 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Wed, 15 Mar 2017 16:26:00 -0700 Subject: [PATCH 1/8] Add mixer client end to end integration test. --- BUILD | 4 + WORKSPACE | 140 ++++++++ src/envoy/mixer/BUILD | 18 +- src/envoy/mixer/integration_test/BUILD | 54 +++ .../mixer/integration_test/attributes.go | 238 +++++++++++++ src/envoy/mixer/integration_test/envoy.conf | 137 +++++++ src/envoy/mixer/integration_test/envoy.go | 103 ++++++ .../mixer/integration_test/http_client.go | 80 +++++ .../mixer/integration_test/http_server.go | 111 ++++++ .../mixer/integration_test/mixer_server.go | 170 +++++++++ .../mixer/integration_test/mixer_test.go | 334 ++++++++++++++++++ src/envoy/mixer/integration_test/setup.go | 64 ++++ 12 files changed, 1447 insertions(+), 6 deletions(-) create mode 100644 src/envoy/mixer/integration_test/BUILD create mode 100644 src/envoy/mixer/integration_test/attributes.go create mode 100644 src/envoy/mixer/integration_test/envoy.conf create mode 100644 src/envoy/mixer/integration_test/envoy.go create mode 100644 src/envoy/mixer/integration_test/http_client.go create mode 100644 src/envoy/mixer/integration_test/http_server.go create mode 100644 src/envoy/mixer/integration_test/mixer_server.go create mode 100644 src/envoy/mixer/integration_test/mixer_test.go create mode 100644 src/envoy/mixer/integration_test/setup.go diff --git a/BUILD b/BUILD index ac06d245289..510620e8246 100644 --- a/BUILD +++ b/BUILD @@ -24,3 +24,7 @@ config_setting( }, visibility = ["//visibility:public"], ) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") + +go_prefix("istio.io/proxy") diff --git a/WORKSPACE b/WORKSPACE index ddfa05d578b..1609584badd 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -96,3 +96,143 @@ http_file( url = "https://storage.googleapis.com/istio-build/manager/ubuntu_xenial_debug-" + DEBUG_BASE_IMAGE_SHA + ".tar.gz", sha256 = DEBUG_BASE_IMAGE_SHA, ) + +# Following go repositories are for building go integration test for mixer filter. +git_repository( + name = "io_bazel_rules_go", + commit = "76c63b5cd0d47c1f2b47ab4953db96c574af1c1d", # Jan 16, 2017 (v0.3.3/0.4.0) + remote = "https://github.com/bazelbuild/rules_go.git", +) + +load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository") + +go_repositories() + +git_repository( + name = "org_pubref_rules_protobuf", + commit = "52c843147b50e0f6d7a7d5bb261410e5097f19d3", # Feb 06 2017 (gogo* support) + remote = "https://github.com/pubref/rules_protobuf", +) + +load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") + +proto_repositories() + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogo_proto_repositories") +gogo_proto_repositories() + +ISTIO_API_BUILD_FILE = """ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") + +go_prefix("istio.io/api") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "mixer/v1", + importmap = { + "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", + "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + "../../external/com_github_googleapis_googleapis", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + "@com_github_googleapis_googleapis//:status_proto", + ], + protos = [ + "mixer/v1/attributes.proto", + "mixer/v1/check.proto", + "mixer/v1/quota.proto", + "mixer/v1/report.proto", + "mixer/v1/service.proto", + ], + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = True, + deps = [ + "@com_github_gogo_protobuf//sortkeys:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + ], +) +""" + +new_git_repository( + name = "com_github_istio_api", + build_file_content = ISTIO_API_BUILD_FILE, + commit = "36787dfa214fb9ba24ce2bfaa54d07ab887141f0", # Feb 27, 2017 (no releases) + remote = "https://github.com/istio/api.git", +) + +GOOGLEAPIS_BUILD_FILE = """ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") +go_prefix("github.com/googleapis/googleapis") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "google/rpc", + protos = [ + "google/rpc/status.proto", + "google/rpc/code.proto", + ], + importmap = { + "google/protobuf/any.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + ], + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + ], + verbose = 0, +) + +load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library") + +cc_proto_library( + name = "cc_status_proto", + protos = [ + "google/rpc/status.proto", + ], + imports = [ + "../../external/com_github_google_protobuf/src", + ], + verbose = 0, +) + +filegroup( + name = "status_proto", + srcs = [ "google/rpc/status.proto" ], +) +""" + +new_git_repository( + name = "com_github_googleapis_googleapis", + build_file_content = GOOGLEAPIS_BUILD_FILE, + commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) + remote = "https://github.com/googleapis/googleapis.git", +) + +new_go_repository( + name = "com_github_google_go_genproto", + commit = "b3e7c2fb04031add52c4817f53f43757ccbf9c18", # Dec 15, 2016 (no releases) + importpath = "google.golang.org/genproto", +) + +new_go_repository( + name = "org_golang_google_grpc", + commit = "708a7f9f3283aa2d4f6132d287d78683babe55c8", # Dec 5, 2016 (v1.0.5) + importpath = "google.golang.org/grpc", +) diff --git a/src/envoy/mixer/BUILD b/src/envoy/mixer/BUILD index 6bf9ea64d72..9d4914d92d1 100644 --- a/src/envoy/mixer/BUILD +++ b/src/envoy/mixer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2016 Google Inc. All Rights Reserved. +# Copyright 2017 Google Inc. 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. @@ -15,7 +15,6 @@ ################################################################################ # - load("@bazel_tools//tools/build_defs/pkg:pkg.bzl", "pkg_tar") load("//src/envoy/mixer:proxy_docker.bzl", "proxy_docker_build") load("@protobuf_git//:protobuf.bzl", "cc_proto_library") @@ -48,6 +47,7 @@ cc_library( cc_binary( name = "envoy", linkstatic = 1, + visibility = [":__subpackages__"], deps = [ ":filter_lib", "@envoy_git//:envoy-main", @@ -80,10 +80,6 @@ pkg_tar( ) proxy_docker_build( - images = [ - {"name": "proxy", "base": "@docker_ubuntu//:xenial"}, - {"name": "proxy_debug", "base": "@ubuntu_xenial_debug//file"}, - ], entrypoint = [ "/usr/local/bin/start_envoy", "-e", @@ -93,6 +89,16 @@ proxy_docker_build( "-t", "/etc/opt/proxy/envoy.conf.template", ], + images = [ + { + "name": "proxy", + "base": "@docker_ubuntu//:xenial", + }, + { + "name": "proxy_debug", + "base": "@ubuntu_xenial_debug//file", + }, + ], ports = ["9090"], repository = "istio", tags = ["manual"], diff --git a/src/envoy/mixer/integration_test/BUILD b/src/envoy/mixer/integration_test/BUILD new file mode 100644 index 00000000000..24e72f413e3 --- /dev/null +++ b/src/envoy/mixer/integration_test/BUILD @@ -0,0 +1,54 @@ +# Copyright 2016 Google Inc. 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. +# +################################################################################ +# + +load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") + +go_library( + name = "go_default_library", + srcs = [ + "attributes.go", + "envoy.go", + "http_client.go", + "http_server.go", + "mixer_server.go", + "setup.go", + ], + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_golang_glog//:go_default_library", + "@com_github_golang_protobuf//proto:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + "@com_github_istio_api//:mixer/v1", + "@org_golang_google_grpc//:go_default_library", + ], +) + +go_test( + name = "mixer_test", + size = "small", + srcs = [ + "mixer_test.go", + ], + data = [ + "envoy.conf", + "//src/envoy/mixer:envoy", + ], + library = ":go_default_library", + # shared memory path /envoy_shared_memory_0 used by Envoy + # hot start is not working in sandbox mode. + local = True, +) diff --git a/src/envoy/mixer/integration_test/attributes.go b/src/envoy/mixer/integration_test/attributes.go new file mode 100644 index 00000000000..9401eed8dff --- /dev/null +++ b/src/envoy/mixer/integration_test/attributes.go @@ -0,0 +1,238 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "encoding/json" + "fmt" + "reflect" + "time" + + ptypes "github.com/gogo/protobuf/types" + mixerpb "istio.io/api/mixer/v1" +) + +type Dictionary map[int32]string + +type Bag struct { + strings map[string]string + int64s map[string]int64 + float64s map[string]float64 + bools map[string]bool + times map[string]time.Time + durations map[string]time.Duration + bytes map[string][]uint8 + stringMaps map[string]map[string]string +} + +func newBag() *Bag { + return &Bag{ + strings: make(map[string]string), + int64s: make(map[string]int64), + float64s: make(map[string]float64), + bools: make(map[string]bool), + times: make(map[string]time.Time), + durations: make(map[string]time.Duration), + bytes: make(map[string][]uint8), + stringMaps: make(map[string]map[string]string), + } +} + +func (rb *Bag) update(dictionary Dictionary, attrs *mixerpb.Attributes) error { + // delete requested attributes + for _, d := range attrs.DeletedAttributes { + if name, present := dictionary[d]; present { + delete(rb.strings, name) + delete(rb.int64s, name) + delete(rb.float64s, name) + delete(rb.bools, name) + delete(rb.times, name) + delete(rb.durations, name) + delete(rb.bytes, name) + delete(rb.stringMaps, name) + } + } + + // apply all attributes + for k, v := range attrs.StringAttributes { + rb.strings[dictionary[k]] = v + } + for k, v := range attrs.Int64Attributes { + rb.int64s[dictionary[k]] = v + } + for k, v := range attrs.DoubleAttributes { + rb.float64s[dictionary[k]] = v + } + for k, v := range attrs.BoolAttributes { + rb.bools[dictionary[k]] = v + } + for k, v := range attrs.TimestampAttributes { + rb.times[dictionary[k]], _ = ptypes.TimestampFromProto(v) + } + for k, v := range attrs.DurationAttributes { + rb.durations[dictionary[k]], _ = ptypes.DurationFromProto(v) + } + for k, v := range attrs.BytesAttributes { + rb.bytes[dictionary[k]] = v + } + for k, v := range attrs.StringMapAttributes { + m := rb.stringMaps[dictionary[k]] + if m == nil { + m = make(map[string]string) + rb.stringMaps[dictionary[k]] = m + } + for k2, v2 := range v.Map { + m[dictionary[k2]] = v2 + } + } + + return nil +} + +func (rb *Bag) getAllKeys() map[string]bool { + all_keys := make(map[string]bool) + for k := range rb.strings { + all_keys[k] = true + } + for k := range rb.int64s { + all_keys[k] = true + } + for k := range rb.float64s { + all_keys[k] = true + } + for k := range rb.bools { + all_keys[k] = true + } + for k := range rb.times { + all_keys[k] = true + } + for k := range rb.durations { + all_keys[k] = true + } + for k := range rb.bytes { + all_keys[k] = true + } + for k := range rb.stringMaps { + all_keys[k] = true + } + return all_keys +} + +func verifyStringMap(actual map[string]string, expected map[string]interface{}) error { + for k, v := range expected { + vstring := v.(string) + // "-" make sure the key does not exist. + if vstring == "-" { + if _, ok := actual[k]; ok { + return fmt.Errorf("key %+v is NOT expected", k) + } + } else { + if val, ok := actual[k]; ok { + // "*" only check key exist + if val != vstring && vstring != "*" { + return fmt.Errorf("key %+v value doesn't match. Actual %+v, expected %+v", + k, val, vstring) + } + } else { + return fmt.Errorf("key %+v is expected", k) + } + } + } + return nil +} + +// Please see the comment at top of mixer_test.go for verification rules +func (rb *Bag) Verify(json_results string) error { + var r map[string]interface{} + if err := json.Unmarshal([]byte(json_results), &r); err != nil { + return fmt.Errorf("unable to decode json %v", err) + } + + all_keys := rb.getAllKeys() + + for k, v := range r { + switch vv := v.(type) { + case string: + // "*" means only checking key. + if vv == "*" { + if _, ok := all_keys[k]; !ok { + return fmt.Errorf("attribute %+v is expected", k) + } + } else { + if val, ok := rb.strings[k]; ok { + vstring := v.(string) + if val != vstring { + return fmt.Errorf("attribute %+v value doesn't match. Actual %+v, expected %+v", + k, val, vstring) + } + } else { + return fmt.Errorf("attribute %+v is expected", k) + } + } + case float64: + // Json converts all integers to float64, + // Our tests only verify size related attributes which are int64 type + if val, ok := rb.int64s[k]; ok { + vint64 := int64(vv) + if val != vint64 { + return fmt.Errorf("attribute %+v value doesn't match. Actual %+v, expected %+v", + k, val, vint64) + } + } else { + return fmt.Errorf("attribute %+v is expected", k) + } + case map[string]interface{}: + if val, ok := rb.stringMaps[k]; ok { + if err := verifyStringMap(val, v.(map[string]interface{})); err != nil { + return fmt.Errorf("attribute %+v StringMap doesn't match: %+v", k, err) + } + } else { + return fmt.Errorf("attribute %+v is expected", k) + } + default: + return fmt.Errorf("attribute %+v is of a type %+v that I don't know how to handle ", + k, reflect.TypeOf(v)) + } + delete(all_keys, k) + + } + + if len(all_keys) > 0 { + var s string + for k, _ := range all_keys { + s += k + ", " + } + return fmt.Errorf("Following attributes are not expected: %s", s) + } + return nil +} + +type Context struct { + dict Dictionary + curr *Bag +} + +func NewContext() *Context { + return &Context{ + curr: newBag(), + } +} + +func (c *Context) Update(attrs *mixerpb.Attributes) error { + if len(attrs.Dictionary) > 0 { + c.dict = attrs.Dictionary + } + return c.curr.update(c.dict, attrs) +} diff --git a/src/envoy/mixer/integration_test/envoy.conf b/src/envoy/mixer/integration_test/envoy.conf new file mode 100644 index 00000000000..896e558a031 --- /dev/null +++ b/src/envoy/mixer/integration_test/envoy.conf @@ -0,0 +1,137 @@ +{ + "listeners": [ + { + "port": 29090, + "bind_to_port": true, + "filters": [ + { + "type": "read", + "name": "http_connection_manager", + "config": { + "codec_type": "auto", + "stat_prefix": "ingress_http", + "route_config": { + "virtual_hosts": [ + { + "name": "backend", + "domains": ["*"], + "routes": [ + { + "timeout_ms": 0, + "prefix": "/", + "cluster": "service1" + } + ] + } + ] + }, + "access_log": [ + { + "path": "/dev/stdout" + } + ], + "filters": [ + { + "type": "both", + "name": "mixer", + "config": { + "mixer_server": "localhost:29091", + "attributes": { + "target.uid": "POD222", + "target.namespace": "XYZ222" + } + } + }, + { + "type": "decoder", + "name": "router", + "config": {} + } + ] + } + } + ] + }, + { + "port": 27070, + "bind_to_port": true, + "filters": [ + { + "type": "read", + "name": "http_connection_manager", + "config": { + "codec_type": "auto", + "stat_prefix": "ingress_http", + "route_config": { + "virtual_hosts": [ + { + "name": "backend", + "domains": ["*"], + "routes": [ + { + "timeout_ms": 0, + "prefix": "/", + "cluster": "service2" + } + ] + } + ] + }, + "access_log": [ + { + "path": "/dev/stdout" + } + ], + "filters": [ + { + "type": "decoder", + "name": "forward_attribute", + "config": { + "attributes": { + "source.uid": "POD11", + "source.namespace": "XYZ11" + } + } + }, + { + "type": "decoder", + "name": "router", + "config": {} + } + ] + } + } + ] + } + ], + "admin": { + "access_log_path": "/dev/stdout", + "port": 29001 + }, + "cluster_manager": { + "clusters": [ + { + "name": "service1", + "connect_timeout_ms": 5000, + "type": "strict_dns", + "lb_type": "round_robin", + "hosts": [ + { + "url": "tcp://localhost:28080" + } + ] + }, + { + "name": "service2", + "connect_timeout_ms": 5000, + "type": "strict_dns", + "lb_type": "round_robin", + "hosts": [ + { + "url": "tcp://localhost:29090" + } + ] + } + ] + } +} diff --git a/src/envoy/mixer/integration_test/envoy.go b/src/envoy/mixer/integration_test/envoy.go new file mode 100644 index 00000000000..0f9a1fc01c7 --- /dev/null +++ b/src/envoy/mixer/integration_test/envoy.go @@ -0,0 +1,103 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "log" + "os" + "os/exec" + "strings" +) + +func getTestBinRootPath() string { + switch { + // custom path + case os.Getenv("TEST_BIN_ROOT") != "": + return os.Getenv("TEST_BIN_ROOT") + // running under bazel + case os.Getenv("TEST_SRCDIR") != "": + return os.Getenv("TEST_SRCDIR") + "/__main__" + // running with native go + case os.Getenv("GOPATH") != "": + list := strings.Split(os.Getenv("GOPATH"), + string(os.PathListSeparator)) + return list[0] + "/bazel-bin" + default: + return "bazel-bin" + } +} + +func getTestDataRootPath() string { + switch { + // custom path + case os.Getenv("TEST_DATA_ROOT") != "": + return os.Getenv("TEST_DATA_ROOT") + // running under bazel + case os.Getenv("TEST_SRCDIR") != "": + return os.Getenv("TEST_SRCDIR") + "/__main__" + // running with native go + case os.Getenv("GOPATH") != "": + list := strings.Split(os.Getenv("GOPATH"), + string(os.PathListSeparator)) + return list[0] + default: + return "" + } +} + +type Envoy struct { + cmd *exec.Cmd +} + +// Run command and return the merged output from stderr and stdout, error code +func Run(name string, args ...string) (s string, err error) { + log.Println(">", name, strings.Join(args, " ")) + c := exec.Command(name, args...) + bytes, err := c.CombinedOutput() + s = string(bytes) + for _, line := range strings.Split(s, "\n") { + log.Println(line) + } + if err != nil { + log.Println(err) + } + return +} + +func NewEnvoy() (*Envoy, error) { + path := getTestBinRootPath() + "/src/envoy/mixer/envoy" + conf := getTestDataRootPath() + + "/src/envoy/mixer/integration_test/envoy.conf" + log.Printf("Envoy binary: %v\n", path) + log.Printf("Envoy config: %v\n", conf) + + cmd := exec.Command(path, "-c", conf, "-l", "debug") + cmd.Stderr = os.Stderr + cmd.Stdout = os.Stdout + return &Envoy{ + cmd: cmd, + }, nil +} + +func (s *Envoy) Start() error { + return s.cmd.Start() +} + +func (s *Envoy) Stop() error { + log.Printf("Kill Envoy ...\n") + err := s.cmd.Process.Kill() + log.Printf("Kill Envoy ... Done\n") + return err +} diff --git a/src/envoy/mixer/integration_test/http_client.go b/src/envoy/mixer/integration_test/http_client.go new file mode 100644 index 00000000000..0212ddf775e --- /dev/null +++ b/src/envoy/mixer/integration_test/http_client.go @@ -0,0 +1,80 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "io/ioutil" + "log" + "net/http" + "net/url" + "strings" +) + +func HTTPGet(url string) (code int, resp_body string, err error) { + log.Println("HTTP GET", url) + client := &http.Client{} + resp, err := client.Get(url) + if err != nil { + log.Println(err) + return 0, "", err + } + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) + resp_body = string(body) + code = resp.StatusCode + log.Println(resp_body) + return code, resp_body, nil +} + +func HTTPPost(url string, content_type string, req_body string) (code int, resp_body string, err error) { + log.Println("HTTP POST", url) + client := &http.Client{} + resp, err := client.Post(url, content_type, strings.NewReader(req_body)) + if err != nil { + log.Println(err) + return 0, "", err + } + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) + resp_body = string(body) + code = resp.StatusCode + log.Println(resp_body) + return code, resp_body, nil +} + +func HTTPGetWithHeaders(l string, headers map[string]string) (code int, resp_body string, err error) { + log.Println("HTTP GET with headers: ", l) + client := &http.Client{} + req := http.Request{} + + req.Header = map[string][]string{} + for k, v := range headers { + req.Header[k] = []string{v} + } + req.Method = http.MethodGet + req.URL, _ = url.Parse(l) + + resp, err := client.Do(&req) + if err != nil { + log.Println(err) + return 0, "", err + } + defer resp.Body.Close() + body, _ := ioutil.ReadAll(resp.Body) + resp_body = string(body) + code = resp.StatusCode + log.Println(resp_body) + return code, resp_body, nil +} diff --git a/src/envoy/mixer/integration_test/http_server.go b/src/envoy/mixer/integration_test/http_server.go new file mode 100644 index 00000000000..77677286b58 --- /dev/null +++ b/src/envoy/mixer/integration_test/http_server.go @@ -0,0 +1,111 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "fmt" + "io/ioutil" + "log" + "net" + "net/http" + "strings" + "time" +) + +const ( + FailHeader = "x-istio-backend-fail" + FailBody = "Bad request from backend." +) + +type HttpServer struct { + port uint16 + lis net.Listener +} + +func handler(w http.ResponseWriter, r *http.Request) { + log.Printf("%v %v %v %v\n", r.Method, r.URL, r.Proto, r.RemoteAddr) + for name, headers := range r.Header { + for _, h := range headers { + log.Printf("%v: %v\n", name, h) + } + } + body, err := ioutil.ReadAll(r.Body) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + // Fail if there is such header. + if r.Header.Get(FailHeader) != "" { + w.WriteHeader(http.StatusBadRequest) + w.Write([]byte(FailBody)) + return + } + + // echo back the Content-Type and Content-Length in the response + for _, k := range []string{"Content-Type", "Content-Length"} { + if v := r.Header.Get(k); v != "" { + w.Header().Set(k, v) + } + } + w.WriteHeader(http.StatusOK) + w.Write(body) +} + +func NewHttpServer(port uint16) (*HttpServer, error) { + log.Printf("Http server listening on port %v\n", port) + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + log.Fatal(err) + return nil, err + } + return &HttpServer{ + port: port, + lis: lis, + }, nil +} + +func (s *HttpServer) Start() { + go func() { + http.HandleFunc("/", handler) + http.Serve(s.lis, nil) + }() + + addr := fmt.Sprintf("http://localhost:%s", s.port) + + const maxAttempts = 10 + for i := 0; i < maxAttempts; i++ { + time.Sleep(time.Second) + client := http.Client{} + log.Println("Pinging the server...") + rsp, err := client.Post( + addr+"/echo", "text/plain", strings.NewReader("PING")) + if err == nil && rsp.StatusCode == http.StatusOK { + log.Println("Got a response...") + png, err := ioutil.ReadAll(rsp.Body) + if err == nil && string(png) == "PING" { + log.Println("Server is up and running...") + return + } + } + log.Println("Will wait a second and try again.") + } +} + +func (s *HttpServer) Stop() { + log.Printf("Close HTTP server\n") + s.lis.Close() + log.Printf("Close HTTP server -- Done\n") +} diff --git a/src/envoy/mixer/integration_test/mixer_server.go b/src/envoy/mixer/integration_test/mixer_server.go new file mode 100644 index 00000000000..21bd513efb1 --- /dev/null +++ b/src/envoy/mixer/integration_test/mixer_server.go @@ -0,0 +1,170 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "fmt" + "io" + "log" + "net" + + "github.com/golang/protobuf/proto" + rpc "github.com/googleapis/googleapis/google/rpc" + "google.golang.org/grpc" + mixerpb "istio.io/api/mixer/v1" +) + +type Handler struct { + ctx *Context + count int + r_status []rpc.Status +} + +func newHandler() *Handler { + return &Handler{ + ctx: NewContext(), + count: 0, + r_status: nil, + } +} + +func (h *Handler) run(attrs *mixerpb.Attributes) *rpc.Status { + h.ctx.Update(attrs) + o := &rpc.Status{} + if h.r_status != nil { + o = &h.r_status[h.count%len(h.r_status)] + } + h.count++ + return o +} + +func (h *Handler) check( + request *mixerpb.CheckRequest, response *mixerpb.CheckResponse) { + response.RequestIndex = request.RequestIndex + response.Result = h.run(request.AttributeUpdate) +} + +func (h *Handler) report( + request *mixerpb.ReportRequest, response *mixerpb.ReportResponse) { + response.RequestIndex = request.RequestIndex + response.Result = h.run(request.AttributeUpdate) +} + +func (h *Handler) quota( + request *mixerpb.QuotaRequest, response *mixerpb.QuotaResponse) { + response.RequestIndex = request.RequestIndex + response.Result = h.run(request.AttributeUpdate) +} + +type MixerServer struct { + lis net.Listener + gs *grpc.Server + check *Handler + report *Handler + quota *Handler +} + +type handlerFunc func(request proto.Message, response proto.Message) + +func (s *MixerServer) streamLoop(stream grpc.ServerStream, + request proto.Message, response proto.Message, handler handlerFunc) error { + for { + // get a single message + if err := stream.RecvMsg(request); err == io.EOF { + return nil + } else if err != nil { + log.Printf("Stream error %s", err) + return err + } + + handler(request, response) + + // produce the response + if err := stream.SendMsg(response); err != nil { + return err + } + + // reset everything to 0 + request.Reset() + response.Reset() + } +} + +func (s *MixerServer) Check(stream mixerpb.Mixer_CheckServer) error { + return s.streamLoop(stream, + new(mixerpb.CheckRequest), + new(mixerpb.CheckResponse), + func(request proto.Message, response proto.Message) { + s.check.check(request.(*mixerpb.CheckRequest), + response.(*mixerpb.CheckResponse)) + }) +} + +func (s *MixerServer) Report(stream mixerpb.Mixer_ReportServer) error { + return s.streamLoop(stream, + new(mixerpb.ReportRequest), + new(mixerpb.ReportResponse), + func(request proto.Message, response proto.Message) { + s.report.report(request.(*mixerpb.ReportRequest), + response.(*mixerpb.ReportResponse)) + }) +} + +func (s *MixerServer) Quota(stream mixerpb.Mixer_QuotaServer) error { + return s.streamLoop(stream, + new(mixerpb.QuotaRequest), + new(mixerpb.QuotaResponse), + func(request proto.Message, response proto.Message) { + s.quota.quota(request.(*mixerpb.QuotaRequest), + response.(*mixerpb.QuotaResponse)) + }) +} + +func NewMixerServer(port uint16) (*MixerServer, error) { + log.Printf("Mixer server listening on port %v\n", port) + lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + if err != nil { + log.Fatalf("failed to listen: %v", err) + return nil, err + } + + var opts []grpc.ServerOption + opts = append(opts, grpc.MaxConcurrentStreams(32)) + opts = append(opts, grpc.MaxMsgSize(1024*1024)) + gs := grpc.NewServer(opts...) + + s := &MixerServer{ + lis: lis, + gs: gs, + check: newHandler(), + report: newHandler(), + quota: newHandler(), + } + mixerpb.RegisterMixerServer(gs, s) + return s, nil +} + +func (s *MixerServer) Start() { + go func() { + _ = s.gs.Serve(s.lis) + log.Printf("Mixer server exited\n") + }() +} + +func (s *MixerServer) Stop() { + log.Printf("Stop Mixer server\n") + s.gs.Stop() + log.Printf("Stop Mixer server -- Done\n") +} diff --git a/src/envoy/mixer/integration_test/mixer_test.go b/src/envoy/mixer/integration_test/mixer_test.go new file mode 100644 index 00000000000..15b1ebf41b0 --- /dev/null +++ b/src/envoy/mixer/integration_test/mixer_test.go @@ -0,0 +1,334 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "fmt" + "testing" + + rpc "github.com/googleapis/googleapis/google/rpc" +) + +const ( + mixerFailMessage = "Unauthenticated by mixer." +) + +// Attributes verification rules +// 1) If value is *, key must exist, but value is not checked. +// 1) If value is -, key must NOT exist. +// 3) At top level attributes, not inside StringMap, all keys must +// be listed. Extra keys are NOT allowed +// 3) Inside StringMap, not need to list all keys. Extra keys are allowed +// +// Attributes provided from envoy config +// * source.id and source.namespace are forwarded from client proxy +// * target.id and target.namespace are from server proxy +// +// HTTP header "x-istio-attributes" is used to forward attributes between +// proxy. It should be removed before calling mixer and backend. +// +// Check attributes from a good GET request +const checkAttributesOkGet = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + } +} +` + +// Report attributes from a good GET request +const reportAttributesOkGet = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + }, + "request.size": 0, + "response.time": "*", + "response.size": 0, + "response.latency": "*", + "response.http.code": 200, + "response.headers": { + "date": "*", + "content-type": "text/plain; charset=utf-8", + "content-length": "0", + ":status": "200", + "server": "envoy" + } +} +` + +// Check attributes from a good POST request +const checkAttributesOkPost = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "POST", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + } +} +` + +// Report attributes from a good POST request +const reportAttributesOkPost = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "POST", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + }, + "request.size": 12, + "response.time": "*", + "response.size": 12, + "response.latency": "*", + "response.http.code": 200, + "response.headers": { + "date": "*", + "content-type": "text/plain", + "content-length": "12", + ":status": "200", + "server": "envoy" + } +} +` + +// Check attributes from a fail GET request from mixer +const checkAttributesMixerFail = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + } +} +` + +// Report attributes from a fail GET request from mixer +const reportAttributesMixerFail = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + }, + "request.size": 0, + "response.time": "*", + "response.size": 41, + "response.latency": "*", + "response.http.code": 401, + "response.headers": { + "date": "*", + "content-type": "text/plain", + "content-length": "41", + ":status": "401", + "server": "envoy" + } +} +` + +// Check attributes from a fail GET request from backend +const checkAttributesBackendFail = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + } +} +` + +// Report attributes from a fail GET request from backend +const reportAttributesBackendFail = ` +{ + "request.host": "localhost:27070", + "request.path": "/echo", + "request.time": "*", + "source.uid": "POD11", + "source.namespace": "XYZ11", + "target.uid": "POD222", + "target.namespace": "XYZ222", + "request.headers": { + ":method": "GET", + ":path": "/echo", + ":authority": "localhost:27070", + "x-forwarded-proto": "http", + "x-istio-attributes": "-", + "x-request-id": "*" + }, + "request.size": 0, + "response.time": "*", + "response.size": 25, + "response.latency": "*", + "response.http.code": 400, + "response.headers": { + "date": "*", + "content-type": "text/plain; charset=utf-8", + "content-length": "25", + ":status": "400", + "server": "envoy" + } +} +` + +func verifyAttributes( + s *TestSetup, tag string, check string, report string, t *testing.T) { + if err := s.mixer.check.ctx.curr.Verify(check); err != nil { + t.Fatalf("Failed to verify %s check: %v\n, Attributes: %+v", + tag, err, s.mixer.check.ctx.curr) + } + if err := s.mixer.report.ctx.curr.Verify(report); err != nil { + t.Fatalf("Failed to verify %s report: %v\n, Attributes: %+v", + tag, err, s.mixer.report.ctx.curr) + } +} + +func TestMixer(t *testing.T) { + s, err := SetUp() + if err != nil { + t.Fatalf("Failed to setup test: %v", err) + } + defer s.TearDown() + + // There is a client proxy with filter "forward_attribute" + // and a server proxy with filter "mixer" calling mixer. + // This request will connect to client proxy, to server proxy + // and to the backend. + url := fmt.Sprintf("http://localhost:%d/echo", ClientProxyPort) + + // Issues a GET echo request with 0 size body + if _, _, err := HTTPGet(url); err != nil { + t.Errorf("Failed in GET request: %v", err) + } + verifyAttributes(&s, "OkGet", + checkAttributesOkGet, reportAttributesOkGet, t) + + // Issues a POST echo request with + if _, _, err := HTTPPost(url, "text/plain", "Hello World!"); err != nil { + t.Errorf("Failed in POST request: %v", err) + } + verifyAttributes(&s, "OkPost", + checkAttributesOkPost, reportAttributesOkPost, t) + + // Issues a failed request caused by mixer + s.mixer.check.r_status = []rpc.Status{ + { + Code: int32(rpc.UNAUTHENTICATED), + Message: mixerFailMessage, + }, + } + code, resp_body, err := HTTPGet(url) + s.mixer.check.r_status = nil + if err != nil { + t.Errorf("Failed in GET request: error: %v", err) + } + if code != 401 { + t.Errorf("Status code 401 is expected.") + } + if resp_body != "UNAUTHENTICATED:"+mixerFailMessage { + t.Errorf("Error response body is not expected.") + } + verifyAttributes(&s, "MixerFail", + checkAttributesMixerFail, reportAttributesMixerFail, t) + + // Issues a failed request caused by backend + headers := map[string]string{} + headers[FailHeader] = "Yes" + code, resp_body, err = HTTPGetWithHeaders(url, headers) + s.mixer.check.r_status = nil + if err != nil { + t.Errorf("Failed in GET request: error: %v", err) + } + if code != 400 { + t.Errorf("Status code 400 is expected.") + } + if resp_body != FailBody { + t.Errorf("Error response body is not expected.") + } + verifyAttributes(&s, "BackendFail", + checkAttributesBackendFail, reportAttributesBackendFail, t) +} diff --git a/src/envoy/mixer/integration_test/setup.go b/src/envoy/mixer/integration_test/setup.go new file mode 100644 index 00000000000..7dc093d2449 --- /dev/null +++ b/src/envoy/mixer/integration_test/setup.go @@ -0,0 +1,64 @@ +// Copyright 2017 Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package test + +import ( + "log" +) + +const ( + // These ports should match with used envoy.conf + // Default is using one in this folder. + ServerProxyPort = 29090 + ClientProxyPort = 27070 + MixerPort = 29091 + BackendPort = 28080 +) + +type TestSetup struct { + envoy *Envoy + mixer *MixerServer + backend *HttpServer +} + +func SetUp() (ts TestSetup, err error) { + ts.envoy, err = NewEnvoy() + if err != nil { + log.Printf("unable to create Envoy %v", err) + } else { + ts.envoy.Start() + } + + ts.mixer, err = NewMixerServer(MixerPort) + if err != nil { + log.Printf("unable to create mixer server %v", err) + } else { + ts.mixer.Start() + } + + ts.backend, err = NewHttpServer(BackendPort) + if err != nil { + log.Printf("unable to create HTTP server %v", err) + } else { + ts.backend.Start() + } + return ts, err +} + +func (ts *TestSetup) TearDown() { + ts.envoy.Stop() + ts.mixer.Stop() + ts.backend.Stop() +} From 8d3867fcf3772885c6e4afc1354c1cab55c8316f Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Wed, 15 Mar 2017 17:14:52 -0700 Subject: [PATCH 2/8] Split some repositories into a separate file. --- WORKSPACE | 120 +----------------- src/envoy/mixer/BUILD | 2 +- .../mixer/integration_test/repositories.bzl | 117 +++++++++++++++++ 3 files changed, 122 insertions(+), 117 deletions(-) create mode 100644 src/envoy/mixer/integration_test/repositories.bzl diff --git a/WORKSPACE b/WORKSPACE index 1609584badd..bb416b64e38 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -98,133 +98,21 @@ http_file( ) # Following go repositories are for building go integration test for mixer filter. -git_repository( - name = "io_bazel_rules_go", - commit = "76c63b5cd0d47c1f2b47ab4953db96c574af1c1d", # Jan 16, 2017 (v0.3.3/0.4.0) - remote = "https://github.com/bazelbuild/rules_go.git", +load( + "//src/envoy/mixer/integration_test:repositories.bzl", + "integration_test_repositories", ) +integration_test_repositories() load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository") - go_repositories() -git_repository( - name = "org_pubref_rules_protobuf", - commit = "52c843147b50e0f6d7a7d5bb261410e5097f19d3", # Feb 06 2017 (gogo* support) - remote = "https://github.com/pubref/rules_protobuf", -) - load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") - proto_repositories() load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogo_proto_repositories") gogo_proto_repositories() -ISTIO_API_BUILD_FILE = """ -package(default_visibility = ["//visibility:public"]) - -load("@io_bazel_rules_go//go:def.bzl", "go_prefix") - -go_prefix("istio.io/api") - -load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") - -gogoslick_proto_library( - name = "mixer/v1", - importmap = { - "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", - "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", - "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", - }, - imports = [ - "../../external/com_github_google_protobuf/src", - "../../external/com_github_googleapis_googleapis", - ], - inputs = [ - "@com_github_google_protobuf//:well_known_protos", - "@com_github_googleapis_googleapis//:status_proto", - ], - protos = [ - "mixer/v1/attributes.proto", - "mixer/v1/check.proto", - "mixer/v1/quota.proto", - "mixer/v1/report.proto", - "mixer/v1/service.proto", - ], - verbose = 0, - visibility = ["//visibility:public"], - with_grpc = True, - deps = [ - "@com_github_gogo_protobuf//sortkeys:go_default_library", - "@com_github_gogo_protobuf//types:go_default_library", - "@com_github_googleapis_googleapis//:google/rpc", - ], -) -""" - -new_git_repository( - name = "com_github_istio_api", - build_file_content = ISTIO_API_BUILD_FILE, - commit = "36787dfa214fb9ba24ce2bfaa54d07ab887141f0", # Feb 27, 2017 (no releases) - remote = "https://github.com/istio/api.git", -) - -GOOGLEAPIS_BUILD_FILE = """ -package(default_visibility = ["//visibility:public"]) - -load("@io_bazel_rules_go//go:def.bzl", "go_prefix") -go_prefix("github.com/googleapis/googleapis") - -load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") - -gogoslick_proto_library( - name = "google/rpc", - protos = [ - "google/rpc/status.proto", - "google/rpc/code.proto", - ], - importmap = { - "google/protobuf/any.proto": "github.com/gogo/protobuf/types", - }, - imports = [ - "../../external/com_github_google_protobuf/src", - ], - inputs = [ - "@com_github_google_protobuf//:well_known_protos", - ], - deps = [ - "@com_github_gogo_protobuf//types:go_default_library", - ], - verbose = 0, -) - -load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library") - -cc_proto_library( - name = "cc_status_proto", - protos = [ - "google/rpc/status.proto", - ], - imports = [ - "../../external/com_github_google_protobuf/src", - ], - verbose = 0, -) - -filegroup( - name = "status_proto", - srcs = [ "google/rpc/status.proto" ], -) -""" - -new_git_repository( - name = "com_github_googleapis_googleapis", - build_file_content = GOOGLEAPIS_BUILD_FILE, - commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) - remote = "https://github.com/googleapis/googleapis.git", -) - new_go_repository( name = "com_github_google_go_genproto", commit = "b3e7c2fb04031add52c4817f53f43757ccbf9c18", # Dec 15, 2016 (no releases) diff --git a/src/envoy/mixer/BUILD b/src/envoy/mixer/BUILD index 9d4914d92d1..4d57f801626 100644 --- a/src/envoy/mixer/BUILD +++ b/src/envoy/mixer/BUILD @@ -1,4 +1,4 @@ -# Copyright 2017 Google Inc. All Rights Reserved. +# Copyright 2016 Google Inc. 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. diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl new file mode 100644 index 00000000000..86a177701bc --- /dev/null +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -0,0 +1,117 @@ + +def integration_test_repositories(): + native.git_repository( + name = "io_bazel_rules_go", + commit = "76c63b5cd0d47c1f2b47ab4953db96c574af1c1d", # Jan 16, 2017 (v0.3.3/0.4.0) + remote = "https://github.com/bazelbuild/rules_go.git", + ) + + native.git_repository( + name = "org_pubref_rules_protobuf", + commit = "52c843147b50e0f6d7a7d5bb261410e5097f19d3", # Feb 06 2017 (gogo* support) + remote = "https://github.com/pubref/rules_protobuf", + ) + + ISTIO_API_BUILD_FILE = """ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") + +go_prefix("istio.io/api") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "mixer/v1", + importmap = { + "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", + "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + "../../external/com_github_googleapis_googleapis", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + "@com_github_googleapis_googleapis//:status_proto", + ], + protos = [ + "mixer/v1/attributes.proto", + "mixer/v1/check.proto", + "mixer/v1/quota.proto", + "mixer/v1/report.proto", + "mixer/v1/service.proto", + ], + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = True, + deps = [ + "@com_github_gogo_protobuf//sortkeys:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + ], +) +""" + + native.new_git_repository( + name = "com_github_istio_api", + build_file_content = ISTIO_API_BUILD_FILE, + commit = "36787dfa214fb9ba24ce2bfaa54d07ab887141f0", # Feb 27, 2017 (no releases) + remote = "https://github.com/istio/api.git", + ) + + GOOGLEAPIS_BUILD_FILE = """ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") +go_prefix("github.com/googleapis/googleapis") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "google/rpc", + protos = [ + "google/rpc/status.proto", + "google/rpc/code.proto", + ], + importmap = { + "google/protobuf/any.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + ], + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + ], + verbose = 0, +) + +load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library") + +cc_proto_library( + name = "cc_status_proto", + protos = [ + "google/rpc/status.proto", + ], + imports = [ + "../../external/com_github_google_protobuf/src", + ], + verbose = 0, +) + +filegroup( + name = "status_proto", + srcs = [ "google/rpc/status.proto" ], +) +""" + + native.new_git_repository( + name = "com_github_googleapis_googleapis", + build_file_content = GOOGLEAPIS_BUILD_FILE, + commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) + remote = "https://github.com/googleapis/googleapis.git", + ) From dc1ff178217227e7877782294bb3c89fced71863 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Thu, 16 Mar 2017 09:04:53 -0700 Subject: [PATCH 3/8] use real mixer for fake mixer_server. --- WORKSPACE | 62 +++++++++++++++- src/envoy/mixer/integration_test/BUILD | 1 + .../mixer/integration_test/repositories.bzl | 71 ++++++++++++++++++- 3 files changed, 130 insertions(+), 4 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index bb416b64e38..3f513f9080a 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -104,7 +104,7 @@ load( ) integration_test_repositories() -load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository") +load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "go_repository", "new_go_repository") go_repositories() load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") @@ -124,3 +124,63 @@ new_go_repository( commit = "708a7f9f3283aa2d4f6132d287d78683babe55c8", # Dec 5, 2016 (v1.0.5) importpath = "google.golang.org/grpc", ) + +new_go_repository( + name = "com_github_golang_glog", + commit = "23def4e6c14b4da8ac2ed8007337bc5eb5007998", # Jan 26, 2016 (no releases) + importpath = "github.com/golang/glog", +) + +new_go_repository( + name = "com_github_ghodss_yaml", + commit = "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", # Dec 6, 2016 (no releases) + importpath = "github.com/ghodss/yaml", +) + +new_go_repository( + name = "in_gopkg_yaml_v2", + commit = "14227de293ca979cf205cd88769fe71ed96a97e2", # Jan 24, 2017 (no releases) + importpath = "gopkg.in/yaml.v2", +) + +new_go_repository( + name = "com_github_spf13_cobra", + commit = "35136c09d8da66b901337c6e86fd8e88a1a255bd", # Jan 30, 2017 (no releases) + importpath = "github.com/spf13/cobra", +) + +new_go_repository( + name = "com_github_spf13_pflag", + commit = "9ff6c6923cfffbcd502984b8e0c80539a94968b7", # Jan 30, 2017 (no releases) + importpath = "github.com/spf13/pflag", +) + +new_go_repository( + name = "com_github_hashicorp_go_multierror", + commit = "ed905158d87462226a13fe39ddf685ea65f1c11f", # Dec 16, 2016 (no releases) + importpath = "github.com/hashicorp/go-multierror", +) + +new_go_repository( + name = "com_github_hashicorp_errwrap", + commit = "7554cd9344cec97297fa6649b055a8c98c2a1e55", # Oct 27, 2014 (no releases) + importpath = "github.com/hashicorp/errwrap", +) + +new_go_repository( + name = "com_github_opentracing_opentracing_go", + commit = "0c3154a3c2ce79d3271985848659870599dfb77c", # Sep 26, 2016 (v1.0.0) + importpath = "github.com/opentracing/opentracing-go", +) + +new_go_repository( + name = "com_github_opentracing_basictracer", + commit = "1b32af207119a14b1b231d451df3ed04a72efebf", # Sep 29, 2016 (no releases) + importpath = "github.com/opentracing/basictracer-go", +) + +go_repository( + name = "com_github_istio_mixer", + commit = "0b2ef133ff6c912855cd059a8f98721ed51d0f93", + importpath = "github.com/istio/mixer", +) diff --git a/src/envoy/mixer/integration_test/BUILD b/src/envoy/mixer/integration_test/BUILD index 24e72f413e3..45a7bb0bf74 100644 --- a/src/envoy/mixer/integration_test/BUILD +++ b/src/envoy/mixer/integration_test/BUILD @@ -33,6 +33,7 @@ go_library( "@com_github_golang_protobuf//proto:go_default_library", "@com_github_googleapis_googleapis//:google/rpc", "@com_github_istio_api//:mixer/v1", + "@com_github_istio_mixer//pkg/api:go_default_library", "@org_golang_google_grpc//:go_default_library", ], ) diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl index 86a177701bc..c34055fb826 100644 --- a/src/envoy/mixer/integration_test/repositories.bzl +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -2,13 +2,13 @@ def integration_test_repositories(): native.git_repository( name = "io_bazel_rules_go", - commit = "76c63b5cd0d47c1f2b47ab4953db96c574af1c1d", # Jan 16, 2017 (v0.3.3/0.4.0) + commit = "9496d79880a7d55b8e4a96f04688d70a374eaaf4", # Jan 16, 2017 (v0.3.3/0.4.0) remote = "https://github.com/bazelbuild/rules_go.git", ) native.git_repository( name = "org_pubref_rules_protobuf", - commit = "52c843147b50e0f6d7a7d5bb261410e5097f19d3", # Feb 06 2017 (gogo* support) + commit = "d42e895387c658eda90276aea018056fcdcb30e4", # Mar 07 2017 (gogo* support) remote = "https://github.com/pubref/rules_protobuf", ) @@ -24,17 +24,20 @@ load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") gogoslick_proto_library( name = "mixer/v1", importmap = { + "gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto", "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", }, imports = [ + "../../external/com_github_gogo_protobuf", "../../external/com_github_google_protobuf/src", "../../external/com_github_googleapis_googleapis", ], inputs = [ "@com_github_google_protobuf//:well_known_protos", "@com_github_googleapis_googleapis//:status_proto", + "@com_github_gogo_protobuf//gogoproto:go_default_library_protos", ], protos = [ "mixer/v1/attributes.proto", @@ -47,17 +50,79 @@ gogoslick_proto_library( visibility = ["//visibility:public"], with_grpc = True, deps = [ + "@com_github_gogo_protobuf//gogoproto:go_default_library", "@com_github_gogo_protobuf//sortkeys:go_default_library", "@com_github_gogo_protobuf//types:go_default_library", "@com_github_googleapis_googleapis//:google/rpc", ], ) + +DESCRIPTOR_FILE_GROUP = [ + "mixer/v1/config/descriptor/attribute_descriptor.proto", + "mixer/v1/config/descriptor/label_descriptor.proto", + "mixer/v1/config/descriptor/log_entry_descriptor.proto", + "mixer/v1/config/descriptor/metric_descriptor.proto", + "mixer/v1/config/descriptor/monitored_resource_descriptor.proto", + "mixer/v1/config/descriptor/principal_descriptor.proto", + "mixer/v1/config/descriptor/quota_descriptor.proto", + "mixer/v1/config/descriptor/value_type.proto", +] + +gogoslick_proto_library( + name = "mixer/v1/config", + importmap = { + "google/protobuf/struct.proto": "github.com/gogo/protobuf/types", + "mixer/v1/config/descriptor/log_entry_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/metric_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/monitored_resource_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/principal_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/quota_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = DESCRIPTOR_FILE_GROUP + [ + "@com_github_google_protobuf//:well_known_protos", + ], + protos = [ + "mixer/v1/config/cfg.proto", + ], + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = False, + deps = [ + ":mixer/v1/config/descriptor", + "@com_github_gogo_protobuf//sortkeys:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + ], +) + +gogoslick_proto_library( + name = "mixer/v1/config/descriptor", + importmap = { + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + ], + protos = DESCRIPTOR_FILE_GROUP, + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = False, + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + ], +) """ native.new_git_repository( name = "com_github_istio_api", build_file_content = ISTIO_API_BUILD_FILE, - commit = "36787dfa214fb9ba24ce2bfaa54d07ab887141f0", # Feb 27, 2017 (no releases) + commit = "2cb09827d7f09a6e88eac2c2249dcb45c5419f09", # Mar. 14, 2017 (no releases) remote = "https://github.com/istio/api.git", ) From c9fbf6fc2f3da21b893019139513b38725affd68 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Fri, 17 Mar 2017 12:05:21 -0700 Subject: [PATCH 4/8] Test repository --- WORKSPACE | 8 +- src/envoy/mixer/integration_test/BUILD | 4 +- .../mixer/integration_test/attributes.go | 101 +------------ .../mixer/integration_test/mixer_server.go | 138 ++++++------------ .../mixer/integration_test/mixer_test.go | 27 ++-- .../mixer/integration_test/repositories.bzl | 32 ++-- src/envoy/mixer/repositories.bzl | 5 +- 7 files changed, 90 insertions(+), 225 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 3f513f9080a..3d0a91c75f6 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -104,8 +104,14 @@ load( ) integration_test_repositories() +load( + "//src/envoy/mixer/integration_test:mmm.bzl", + "mmm", +) +mmm() + load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "go_repository", "new_go_repository") -go_repositories() +#go_repositories() load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") proto_repositories() diff --git a/src/envoy/mixer/integration_test/BUILD b/src/envoy/mixer/integration_test/BUILD index 45a7bb0bf74..7376bebb266 100644 --- a/src/envoy/mixer/integration_test/BUILD +++ b/src/envoy/mixer/integration_test/BUILD @@ -20,7 +20,6 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ - "attributes.go", "envoy.go", "http_client.go", "http_server.go", @@ -34,6 +33,9 @@ go_library( "@com_github_googleapis_googleapis//:google/rpc", "@com_github_istio_api//:mixer/v1", "@com_github_istio_mixer//pkg/api:go_default_library", + "@com_github_istio_mixer//pkg/attribute:go_default_library", + "@com_github_istio_mixer//pkg/pool:go_default_library", + "@com_github_istio_mixer//pkg/tracing:go_default_library", "@org_golang_google_grpc//:go_default_library", ], ) diff --git a/src/envoy/mixer/integration_test/attributes.go b/src/envoy/mixer/integration_test/attributes.go index 9401eed8dff..412e99306e5 100644 --- a/src/envoy/mixer/integration_test/attributes.go +++ b/src/envoy/mixer/integration_test/attributes.go @@ -18,90 +18,11 @@ import ( "encoding/json" "fmt" "reflect" - "time" - ptypes "github.com/gogo/protobuf/types" - mixerpb "istio.io/api/mixer/v1" + "github.com/istio/mixer/pkg/attribute" ) -type Dictionary map[int32]string - -type Bag struct { - strings map[string]string - int64s map[string]int64 - float64s map[string]float64 - bools map[string]bool - times map[string]time.Time - durations map[string]time.Duration - bytes map[string][]uint8 - stringMaps map[string]map[string]string -} - -func newBag() *Bag { - return &Bag{ - strings: make(map[string]string), - int64s: make(map[string]int64), - float64s: make(map[string]float64), - bools: make(map[string]bool), - times: make(map[string]time.Time), - durations: make(map[string]time.Duration), - bytes: make(map[string][]uint8), - stringMaps: make(map[string]map[string]string), - } -} - -func (rb *Bag) update(dictionary Dictionary, attrs *mixerpb.Attributes) error { - // delete requested attributes - for _, d := range attrs.DeletedAttributes { - if name, present := dictionary[d]; present { - delete(rb.strings, name) - delete(rb.int64s, name) - delete(rb.float64s, name) - delete(rb.bools, name) - delete(rb.times, name) - delete(rb.durations, name) - delete(rb.bytes, name) - delete(rb.stringMaps, name) - } - } - - // apply all attributes - for k, v := range attrs.StringAttributes { - rb.strings[dictionary[k]] = v - } - for k, v := range attrs.Int64Attributes { - rb.int64s[dictionary[k]] = v - } - for k, v := range attrs.DoubleAttributes { - rb.float64s[dictionary[k]] = v - } - for k, v := range attrs.BoolAttributes { - rb.bools[dictionary[k]] = v - } - for k, v := range attrs.TimestampAttributes { - rb.times[dictionary[k]], _ = ptypes.TimestampFromProto(v) - } - for k, v := range attrs.DurationAttributes { - rb.durations[dictionary[k]], _ = ptypes.DurationFromProto(v) - } - for k, v := range attrs.BytesAttributes { - rb.bytes[dictionary[k]] = v - } - for k, v := range attrs.StringMapAttributes { - m := rb.stringMaps[dictionary[k]] - if m == nil { - m = make(map[string]string) - rb.stringMaps[dictionary[k]] = m - } - for k2, v2 := range v.Map { - m[dictionary[k2]] = v2 - } - } - - return nil -} - -func (rb *Bag) getAllKeys() map[string]bool { +func (rb *attribute.MutableBag) getAllKeys() map[string]bool { all_keys := make(map[string]bool) for k := range rb.strings { all_keys[k] = true @@ -218,21 +139,3 @@ func (rb *Bag) Verify(json_results string) error { } return nil } - -type Context struct { - dict Dictionary - curr *Bag -} - -func NewContext() *Context { - return &Context{ - curr: newBag(), - } -} - -func (c *Context) Update(attrs *mixerpb.Attributes) error { - if len(attrs.Dictionary) > 0 { - c.dict = attrs.Dictionary - } - return c.curr.update(c.dict, attrs) -} diff --git a/src/envoy/mixer/integration_test/mixer_server.go b/src/envoy/mixer/integration_test/mixer_server.go index 21bd513efb1..fa129baf152 100644 --- a/src/envoy/mixer/integration_test/mixer_server.go +++ b/src/envoy/mixer/integration_test/mixer_server.go @@ -15,126 +15,81 @@ package test import ( + "context" "fmt" - "io" "log" "net" - "github.com/golang/protobuf/proto" rpc "github.com/googleapis/googleapis/google/rpc" "google.golang.org/grpc" + mixerpb "istio.io/api/mixer/v1" + "istio.io/mixer/pkg/api" + "istio.io/mixer/pkg/attribute" + "istio.io/mixer/pkg/pool" + "istio.io/mixer/pkg/tracing" ) type Handler struct { - ctx *Context + bag attribute.MutableBag count int - r_status []rpc.Status + r_status rpc.Status } func newHandler() *Handler { return &Handler{ - ctx: NewContext(), + bag: nil, count: 0, - r_status: nil, + r_status: rpc.Status{}, } } -func (h *Handler) run(attrs *mixerpb.Attributes) *rpc.Status { - h.ctx.Update(attrs) - o := &rpc.Status{} - if h.r_status != nil { - o = &h.r_status[h.count%len(h.r_status)] - } +func (h *Handler) run(bag attribute.MutableBag) rpc.Status { + h.bag = bag h.count++ - return o -} - -func (h *Handler) check( - request *mixerpb.CheckRequest, response *mixerpb.CheckResponse) { - response.RequestIndex = request.RequestIndex - response.Result = h.run(request.AttributeUpdate) -} - -func (h *Handler) report( - request *mixerpb.ReportRequest, response *mixerpb.ReportResponse) { - response.RequestIndex = request.RequestIndex - response.Result = h.run(request.AttributeUpdate) -} - -func (h *Handler) quota( - request *mixerpb.QuotaRequest, response *mixerpb.QuotaResponse) { - response.RequestIndex = request.RequestIndex - response.Result = h.run(request.AttributeUpdate) + return h.r_status } type MixerServer struct { - lis net.Listener - gs *grpc.Server + lis net.Listener + gs *grpc.Server + gp *pool.GoroutinePool + s mixerpb.MixerServer + check *Handler report *Handler quota *Handler } -type handlerFunc func(request proto.Message, response proto.Message) - -func (s *MixerServer) streamLoop(stream grpc.ServerStream, - request proto.Message, response proto.Message, handler handlerFunc) error { - for { - // get a single message - if err := stream.RecvMsg(request); err == io.EOF { - return nil - } else if err != nil { - log.Printf("Stream error %s", err) - return err - } - - handler(request, response) - - // produce the response - if err := stream.SendMsg(response); err != nil { - return err - } - - // reset everything to 0 - request.Reset() - response.Reset() - } -} - -func (s *MixerServer) Check(stream mixerpb.Mixer_CheckServer) error { - return s.streamLoop(stream, - new(mixerpb.CheckRequest), - new(mixerpb.CheckResponse), - func(request proto.Message, response proto.Message) { - s.check.check(request.(*mixerpb.CheckRequest), - response.(*mixerpb.CheckResponse)) - }) +func (ts *MixerServer) Check(ctx context.Context, bag attribute.MutableBag, + request *mixerpb.CheckRequest, response *mixerpb.CheckResponse) { + response.RequestIndex = request.RequestIndex + response.Result = ts.check.run(bag) } -func (s *MixerServer) Report(stream mixerpb.Mixer_ReportServer) error { - return s.streamLoop(stream, - new(mixerpb.ReportRequest), - new(mixerpb.ReportResponse), - func(request proto.Message, response proto.Message) { - s.report.report(request.(*mixerpb.ReportRequest), - response.(*mixerpb.ReportResponse)) - }) +func (ts *MixerServer) Report(ctx context.Context, bag attribute.MutableBag, + request *mixerpb.ReportRequest, response *mixerpb.ReportResponse) { + response.RequestIndex = request.RequestIndex + response.Result = ts.report.run(bag) } -func (s *MixerServer) Quota(stream mixerpb.Mixer_QuotaServer) error { - return s.streamLoop(stream, - new(mixerpb.QuotaRequest), - new(mixerpb.QuotaResponse), - func(request proto.Message, response proto.Message) { - s.quota.quota(request.(*mixerpb.QuotaRequest), - response.(*mixerpb.QuotaResponse)) - }) +func (ts *MixerServer) Quota(ctx context.Context, bag attribute.MutableBag, + request *mixerpb.QuotaRequest, response *mixerpb.QuotaResponse) { + response.RequestIndex = request.RequestIndex + response.Result = ts.quota.run(bag) + response.Amount = 0 } func NewMixerServer(port uint16) (*MixerServer, error) { log.Printf("Mixer server listening on port %v\n", port) - lis, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) + s := &MixerServer{ + check: newHandler(), + report: newHandler(), + quota: newHandler(), + } + + var err error + s.lis, err = net.Listen("tcp", fmt.Sprintf(":%d", port)) if err != nil { log.Fatalf("failed to listen: %v", err) return nil, err @@ -143,16 +98,13 @@ func NewMixerServer(port uint16) (*MixerServer, error) { var opts []grpc.ServerOption opts = append(opts, grpc.MaxConcurrentStreams(32)) opts = append(opts, grpc.MaxMsgSize(1024*1024)) - gs := grpc.NewServer(opts...) + s.gs = grpc.NewServer(opts...) - s := &MixerServer{ - lis: lis, - gs: gs, - check: newHandler(), - report: newHandler(), - quota: newHandler(), - } - mixerpb.RegisterMixerServer(gs, s) + s.gp = pool.NewGoroutinePool(128, false) + s.gp.AddWorkers(32) + + s.s = api.NewGRPCServer(s, tracing.DisabledTracer(), s.gp) + mixerpb.RegisterMixerServer(s.gs, s.s) return s, nil } diff --git a/src/envoy/mixer/integration_test/mixer_test.go b/src/envoy/mixer/integration_test/mixer_test.go index 15b1ebf41b0..45f5e3835de 100644 --- a/src/envoy/mixer/integration_test/mixer_test.go +++ b/src/envoy/mixer/integration_test/mixer_test.go @@ -257,14 +257,14 @@ const reportAttributesBackendFail = ` func verifyAttributes( s *TestSetup, tag string, check string, report string, t *testing.T) { - if err := s.mixer.check.ctx.curr.Verify(check); err != nil { - t.Fatalf("Failed to verify %s check: %v\n, Attributes: %+v", - tag, err, s.mixer.check.ctx.curr) - } - if err := s.mixer.report.ctx.curr.Verify(report); err != nil { - t.Fatalf("Failed to verify %s report: %v\n, Attributes: %+v", - tag, err, s.mixer.report.ctx.curr) - } + /* if err := s.mixer.check.ctx.curr.Verify(check); err != nil { + t.Fatalf("Failed to verify %s check: %v\n, Attributes: %+v", + tag, err, s.mixer.check.ctx.curr) + } + if err := s.mixer.report.ctx.curr.Verify(report); err != nil { + t.Fatalf("Failed to verify %s report: %v\n, Attributes: %+v", + tag, err, s.mixer.report.ctx.curr) + } */ } func TestMixer(t *testing.T) { @@ -295,14 +295,12 @@ func TestMixer(t *testing.T) { checkAttributesOkPost, reportAttributesOkPost, t) // Issues a failed request caused by mixer - s.mixer.check.r_status = []rpc.Status{ - { - Code: int32(rpc.UNAUTHENTICATED), - Message: mixerFailMessage, - }, + s.mixer.check.r_status = rpc.Status{ + Code: int32(rpc.UNAUTHENTICATED), + Message: mixerFailMessage, } code, resp_body, err := HTTPGet(url) - s.mixer.check.r_status = nil + s.mixer.check.r_status = rpc.Status{} if err != nil { t.Errorf("Failed in GET request: error: %v", err) } @@ -319,7 +317,6 @@ func TestMixer(t *testing.T) { headers := map[string]string{} headers[FailHeader] = "Yes" code, resp_body, err = HTTPGetWithHeaders(url, headers) - s.mixer.check.r_status = nil if err != nil { t.Errorf("Failed in GET request: error: %v", err) } diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl index c34055fb826..c030f77d744 100644 --- a/src/envoy/mixer/integration_test/repositories.bzl +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -1,17 +1,5 @@ -def integration_test_repositories(): - native.git_repository( - name = "io_bazel_rules_go", - commit = "9496d79880a7d55b8e4a96f04688d70a374eaaf4", # Jan 16, 2017 (v0.3.3/0.4.0) - remote = "https://github.com/bazelbuild/rules_go.git", - ) - - native.git_repository( - name = "org_pubref_rules_protobuf", - commit = "d42e895387c658eda90276aea018056fcdcb30e4", # Mar 07 2017 (gogo* support) - remote = "https://github.com/pubref/rules_protobuf", - ) - +def go_istio_api_repositories(): ISTIO_API_BUILD_FILE = """ package(default_visibility = ["//visibility:public"]) @@ -126,6 +114,7 @@ gogoslick_proto_library( remote = "https://github.com/istio/api.git", ) +def go_googleapis_repositories(): GOOGLEAPIS_BUILD_FILE = """ package(default_visibility = ["//visibility:public"]) @@ -180,3 +169,20 @@ filegroup( commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) remote = "https://github.com/googleapis/googleapis.git", ) + +def integration_test_repositories(): + native.git_repository( + name = "io_bazel_rules_go", + commit = "9496d79880a7d55b8e4a96f04688d70a374eaaf4", # Jan 16, 2017 (v0.3.3/0.4.0) + remote = "https://github.com/bazelbuild/rules_go.git", + ) + + native.git_repository( + name = "org_pubref_rules_protobuf", + commit = "d42e895387c658eda90276aea018056fcdcb30e4", # Mar 07 2017 (gogo* support) + remote = "https://github.com/pubref/rules_protobuf", + ) + + go_istio_api_repositories() + go_googleapis_repositories() + diff --git a/src/envoy/mixer/repositories.bzl b/src/envoy/mixer/repositories.bzl index 9d06b24a14b..3e20f4f4bd3 100644 --- a/src/envoy/mixer/repositories.bzl +++ b/src/envoy/mixer/repositories.bzl @@ -18,10 +18,9 @@ MIXER_CLIENT = "1d6b587755846fe1b3a44fb53e3ab9ce0534af2c" def mixer_client_repositories(bind=True): - native.git_repository( + native.local_repository( name = "mixerclient_git", - commit = MIXER_CLIENT, - remote = "https://github.com/istio/mixerclient.git", + path = "/usr/local/google/home/qiwzhang/github/istio/mixerclient", ) if bind: From 3b89772ee80fefd1c376dcba6d5ddff9f739b863 Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Fri, 17 Mar 2017 18:14:29 -0700 Subject: [PATCH 5/8] use mixer bzl file. --- WORKSPACE | 99 ++------- .../mixer/integration_test/repositories.bzl | 192 +----------------- src/envoy/mixer/repositories.bzl | 5 +- 3 files changed, 24 insertions(+), 272 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index 3d0a91c75f6..fee6b5d782d 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -98,95 +98,22 @@ http_file( ) # Following go repositories are for building go integration test for mixer filter. -load( - "//src/envoy/mixer/integration_test:repositories.bzl", - "integration_test_repositories", -) -integration_test_repositories() - -load( - "//src/envoy/mixer/integration_test:mmm.bzl", - "mmm", -) -mmm() - -load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "go_repository", "new_go_repository") -#go_repositories() - -load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") -proto_repositories() - -load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogo_proto_repositories") -gogo_proto_repositories() - -new_go_repository( - name = "com_github_google_go_genproto", - commit = "b3e7c2fb04031add52c4817f53f43757ccbf9c18", # Dec 15, 2016 (no releases) - importpath = "google.golang.org/genproto", -) - -new_go_repository( - name = "org_golang_google_grpc", - commit = "708a7f9f3283aa2d4f6132d287d78683babe55c8", # Dec 5, 2016 (v1.0.5) - importpath = "google.golang.org/grpc", -) - -new_go_repository( - name = "com_github_golang_glog", - commit = "23def4e6c14b4da8ac2ed8007337bc5eb5007998", # Jan 26, 2016 (no releases) - importpath = "github.com/golang/glog", +git_repository( + name = "io_bazel_rules_go", + commit = "9496d79880a7d55b8e4a96f04688d70a374eaaf4", # Mar 3, 2017 (v0.4.1) + remote = "https://github.com/bazelbuild/rules_go.git", ) -new_go_repository( - name = "com_github_ghodss_yaml", - commit = "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", # Dec 6, 2016 (no releases) - importpath = "github.com/ghodss/yaml", +git_repository( + name = "org_pubref_rules_protobuf", + commit = "d42e895387c658eda90276aea018056fcdcb30e4", # Mar 07 2017 (gogo* support) + remote = "https://github.com/pubref/rules_protobuf", ) -new_go_repository( - name = "in_gopkg_yaml_v2", - commit = "14227de293ca979cf205cd88769fe71ed96a97e2", # Jan 24, 2017 (no releases) - importpath = "gopkg.in/yaml.v2", +local_repository( + name = "git_istio_mixer_bzl", + path = "/usr/local/google/home/qiwzhang/github/istio/mixer", ) -new_go_repository( - name = "com_github_spf13_cobra", - commit = "35136c09d8da66b901337c6e86fd8e88a1a255bd", # Jan 30, 2017 (no releases) - importpath = "github.com/spf13/cobra", -) - -new_go_repository( - name = "com_github_spf13_pflag", - commit = "9ff6c6923cfffbcd502984b8e0c80539a94968b7", # Jan 30, 2017 (no releases) - importpath = "github.com/spf13/pflag", -) - -new_go_repository( - name = "com_github_hashicorp_go_multierror", - commit = "ed905158d87462226a13fe39ddf685ea65f1c11f", # Dec 16, 2016 (no releases) - importpath = "github.com/hashicorp/go-multierror", -) - -new_go_repository( - name = "com_github_hashicorp_errwrap", - commit = "7554cd9344cec97297fa6649b055a8c98c2a1e55", # Oct 27, 2014 (no releases) - importpath = "github.com/hashicorp/errwrap", -) - -new_go_repository( - name = "com_github_opentracing_opentracing_go", - commit = "0c3154a3c2ce79d3271985848659870599dfb77c", # Sep 26, 2016 (v1.0.0) - importpath = "github.com/opentracing/opentracing-go", -) - -new_go_repository( - name = "com_github_opentracing_basictracer", - commit = "1b32af207119a14b1b231d451df3ed04a72efebf", # Sep 29, 2016 (no releases) - importpath = "github.com/opentracing/basictracer-go", -) - -go_repository( - name = "com_github_istio_mixer", - commit = "0b2ef133ff6c912855cd059a8f98721ed51d0f93", - importpath = "github.com/istio/mixer", -) +load("//src/envoy/mixer/integration_test:repositories.bzl", "test_repositories") +test_repositories() \ No newline at end of file diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl index c030f77d744..297f0c9017e 100644 --- a/src/envoy/mixer/integration_test/repositories.bzl +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -1,188 +1,12 @@ -def go_istio_api_repositories(): - ISTIO_API_BUILD_FILE = """ -package(default_visibility = ["//visibility:public"]) +load("@git_istio_mixer_bzl//:repositories.bzl", "go_mixer_repositories") +load("@io_bazel_rules_go//go:def.bzl", "go_repository") -load("@io_bazel_rules_go//go:def.bzl", "go_prefix") - -go_prefix("istio.io/api") - -load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") - -gogoslick_proto_library( - name = "mixer/v1", - importmap = { - "gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto", - "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", - "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", - "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", - }, - imports = [ - "../../external/com_github_gogo_protobuf", - "../../external/com_github_google_protobuf/src", - "../../external/com_github_googleapis_googleapis", - ], - inputs = [ - "@com_github_google_protobuf//:well_known_protos", - "@com_github_googleapis_googleapis//:status_proto", - "@com_github_gogo_protobuf//gogoproto:go_default_library_protos", - ], - protos = [ - "mixer/v1/attributes.proto", - "mixer/v1/check.proto", - "mixer/v1/quota.proto", - "mixer/v1/report.proto", - "mixer/v1/service.proto", - ], - verbose = 0, - visibility = ["//visibility:public"], - with_grpc = True, - deps = [ - "@com_github_gogo_protobuf//gogoproto:go_default_library", - "@com_github_gogo_protobuf//sortkeys:go_default_library", - "@com_github_gogo_protobuf//types:go_default_library", - "@com_github_googleapis_googleapis//:google/rpc", - ], -) - -DESCRIPTOR_FILE_GROUP = [ - "mixer/v1/config/descriptor/attribute_descriptor.proto", - "mixer/v1/config/descriptor/label_descriptor.proto", - "mixer/v1/config/descriptor/log_entry_descriptor.proto", - "mixer/v1/config/descriptor/metric_descriptor.proto", - "mixer/v1/config/descriptor/monitored_resource_descriptor.proto", - "mixer/v1/config/descriptor/principal_descriptor.proto", - "mixer/v1/config/descriptor/quota_descriptor.proto", - "mixer/v1/config/descriptor/value_type.proto", -] - -gogoslick_proto_library( - name = "mixer/v1/config", - importmap = { - "google/protobuf/struct.proto": "github.com/gogo/protobuf/types", - "mixer/v1/config/descriptor/log_entry_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", - "mixer/v1/config/descriptor/metric_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", - "mixer/v1/config/descriptor/monitored_resource_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", - "mixer/v1/config/descriptor/principal_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", - "mixer/v1/config/descriptor/quota_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", - }, - imports = [ - "../../external/com_github_google_protobuf/src", - ], - inputs = DESCRIPTOR_FILE_GROUP + [ - "@com_github_google_protobuf//:well_known_protos", - ], - protos = [ - "mixer/v1/config/cfg.proto", - ], - verbose = 0, - visibility = ["//visibility:public"], - with_grpc = False, - deps = [ - ":mixer/v1/config/descriptor", - "@com_github_gogo_protobuf//sortkeys:go_default_library", - "@com_github_gogo_protobuf//types:go_default_library", - "@com_github_googleapis_googleapis//:google/rpc", - ], -) - -gogoslick_proto_library( - name = "mixer/v1/config/descriptor", - importmap = { - "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", - }, - imports = [ - "../../external/com_github_google_protobuf/src", - ], - inputs = [ - "@com_github_google_protobuf//:well_known_protos", - ], - protos = DESCRIPTOR_FILE_GROUP, - verbose = 0, - visibility = ["//visibility:public"], - with_grpc = False, - deps = [ - "@com_github_gogo_protobuf//types:go_default_library", - ], -) -""" - - native.new_git_repository( - name = "com_github_istio_api", - build_file_content = ISTIO_API_BUILD_FILE, - commit = "2cb09827d7f09a6e88eac2c2249dcb45c5419f09", # Mar. 14, 2017 (no releases) - remote = "https://github.com/istio/api.git", +def test_repositories(): + go_mixer_repositories() + go_repository( + name = "com_github_istio_mixer", + commit = "0b2ef133ff6c912855cd059a8f98721ed51d0f93", + importpath = "github.com/istio/mixer", ) - -def go_googleapis_repositories(): - GOOGLEAPIS_BUILD_FILE = """ -package(default_visibility = ["//visibility:public"]) - -load("@io_bazel_rules_go//go:def.bzl", "go_prefix") -go_prefix("github.com/googleapis/googleapis") - -load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") - -gogoslick_proto_library( - name = "google/rpc", - protos = [ - "google/rpc/status.proto", - "google/rpc/code.proto", - ], - importmap = { - "google/protobuf/any.proto": "github.com/gogo/protobuf/types", - }, - imports = [ - "../../external/com_github_google_protobuf/src", - ], - inputs = [ - "@com_github_google_protobuf//:well_known_protos", - ], - deps = [ - "@com_github_gogo_protobuf//types:go_default_library", - ], - verbose = 0, -) - -load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library") - -cc_proto_library( - name = "cc_status_proto", - protos = [ - "google/rpc/status.proto", - ], - imports = [ - "../../external/com_github_google_protobuf/src", - ], - verbose = 0, -) - -filegroup( - name = "status_proto", - srcs = [ "google/rpc/status.proto" ], -) -""" - - native.new_git_repository( - name = "com_github_googleapis_googleapis", - build_file_content = GOOGLEAPIS_BUILD_FILE, - commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) - remote = "https://github.com/googleapis/googleapis.git", - ) - -def integration_test_repositories(): - native.git_repository( - name = "io_bazel_rules_go", - commit = "9496d79880a7d55b8e4a96f04688d70a374eaaf4", # Jan 16, 2017 (v0.3.3/0.4.0) - remote = "https://github.com/bazelbuild/rules_go.git", - ) - - native.git_repository( - name = "org_pubref_rules_protobuf", - commit = "d42e895387c658eda90276aea018056fcdcb30e4", # Mar 07 2017 (gogo* support) - remote = "https://github.com/pubref/rules_protobuf", - ) - - go_istio_api_repositories() - go_googleapis_repositories() diff --git a/src/envoy/mixer/repositories.bzl b/src/envoy/mixer/repositories.bzl index 3e20f4f4bd3..9d06b24a14b 100644 --- a/src/envoy/mixer/repositories.bzl +++ b/src/envoy/mixer/repositories.bzl @@ -18,9 +18,10 @@ MIXER_CLIENT = "1d6b587755846fe1b3a44fb53e3ab9ce0534af2c" def mixer_client_repositories(bind=True): - native.local_repository( + native.git_repository( name = "mixerclient_git", - path = "/usr/local/google/home/qiwzhang/github/istio/mixerclient", + commit = MIXER_CLIENT, + remote = "https://github.com/istio/mixerclient.git", ) if bind: From e275f40d1899953dbbe8d94771aa74a49a0905de Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Sun, 19 Mar 2017 21:55:42 -0700 Subject: [PATCH 6/8] Use mixer repositories --- src/envoy/mixer/integration_test/BUILD | 1 + .../mixer/integration_test/attributes.go | 57 +++++-------------- src/envoy/mixer/integration_test/envoy.conf | 15 +++-- .../mixer/integration_test/mixer_server.go | 18 +++--- .../mixer/integration_test/mixer_test.go | 18 +++--- .../mixer/integration_test/repositories.bzl | 2 +- 6 files changed, 46 insertions(+), 65 deletions(-) diff --git a/src/envoy/mixer/integration_test/BUILD b/src/envoy/mixer/integration_test/BUILD index 7376bebb266..c45865457ce 100644 --- a/src/envoy/mixer/integration_test/BUILD +++ b/src/envoy/mixer/integration_test/BUILD @@ -20,6 +20,7 @@ load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test") go_library( name = "go_default_library", srcs = [ + "attributes.go", "envoy.go", "http_client.go", "http_server.go", diff --git a/src/envoy/mixer/integration_test/attributes.go b/src/envoy/mixer/integration_test/attributes.go index 412e99306e5..4c97208fd4b 100644 --- a/src/envoy/mixer/integration_test/attributes.go +++ b/src/envoy/mixer/integration_test/attributes.go @@ -19,38 +19,9 @@ import ( "fmt" "reflect" - "github.com/istio/mixer/pkg/attribute" + "istio.io/mixer/pkg/attribute" ) -func (rb *attribute.MutableBag) getAllKeys() map[string]bool { - all_keys := make(map[string]bool) - for k := range rb.strings { - all_keys[k] = true - } - for k := range rb.int64s { - all_keys[k] = true - } - for k := range rb.float64s { - all_keys[k] = true - } - for k := range rb.bools { - all_keys[k] = true - } - for k := range rb.times { - all_keys[k] = true - } - for k := range rb.durations { - all_keys[k] = true - } - for k := range rb.bytes { - all_keys[k] = true - } - for k := range rb.stringMaps { - all_keys[k] = true - } - return all_keys -} - func verifyStringMap(actual map[string]string, expected map[string]interface{}) error { for k, v := range expected { vstring := v.(string) @@ -75,28 +46,30 @@ func verifyStringMap(actual map[string]string, expected map[string]interface{}) } // Please see the comment at top of mixer_test.go for verification rules -func (rb *Bag) Verify(json_results string) error { +func Verify(b *attribute.MutableBag, json_results string) error { var r map[string]interface{} if err := json.Unmarshal([]byte(json_results), &r); err != nil { return fmt.Errorf("unable to decode json %v", err) } - all_keys := rb.getAllKeys() + all_keys := make(map[string]bool) + for _, k := range b.Names() { + all_keys[k] = true + } for k, v := range r { switch vv := v.(type) { case string: // "*" means only checking key. if vv == "*" { - if _, ok := all_keys[k]; !ok { + if _, ok := b.Get(k); !ok { return fmt.Errorf("attribute %+v is expected", k) } } else { - if val, ok := rb.strings[k]; ok { - vstring := v.(string) - if val != vstring { + if val, ok := b.Get(k); ok { + if val.(string) != v.(string) { return fmt.Errorf("attribute %+v value doesn't match. Actual %+v, expected %+v", - k, val, vstring) + k, val.(string), v.(string)) } } else { return fmt.Errorf("attribute %+v is expected", k) @@ -105,18 +78,18 @@ func (rb *Bag) Verify(json_results string) error { case float64: // Json converts all integers to float64, // Our tests only verify size related attributes which are int64 type - if val, ok := rb.int64s[k]; ok { + if val, ok := b.Get(k); ok { vint64 := int64(vv) - if val != vint64 { + if val.(int64) != vint64 { return fmt.Errorf("attribute %+v value doesn't match. Actual %+v, expected %+v", - k, val, vint64) + k, val.(int64), vint64) } } else { return fmt.Errorf("attribute %+v is expected", k) } case map[string]interface{}: - if val, ok := rb.stringMaps[k]; ok { - if err := verifyStringMap(val, v.(map[string]interface{})); err != nil { + if val, ok := b.Get(k); ok { + if err := verifyStringMap(val.(map[string]string), v.(map[string]interface{})); err != nil { return fmt.Errorf("attribute %+v StringMap doesn't match: %+v", k, err) } } else { diff --git a/src/envoy/mixer/integration_test/envoy.conf b/src/envoy/mixer/integration_test/envoy.conf index 896e558a031..2083d7f4e5a 100644 --- a/src/envoy/mixer/integration_test/envoy.conf +++ b/src/envoy/mixer/integration_test/envoy.conf @@ -19,7 +19,11 @@ { "timeout_ms": 0, "prefix": "/", - "cluster": "service1" + "cluster": "service1", + "opaque_config": { + "mixer_control": "on", + "mixer_forward": "off" + } } ] } @@ -32,11 +36,11 @@ ], "filters": [ { - "type": "both", + "type": "decoder", "name": "mixer", "config": { "mixer_server": "localhost:29091", - "attributes": { + "mixer_attributes": { "target.uid": "POD222", "target.namespace": "XYZ222" } @@ -85,9 +89,10 @@ "filters": [ { "type": "decoder", - "name": "forward_attribute", + "name": "mixer", "config": { - "attributes": { + "mixer_server": "localhost:29091", + "forward_attributes": { "source.uid": "POD11", "source.namespace": "XYZ11" } diff --git a/src/envoy/mixer/integration_test/mixer_server.go b/src/envoy/mixer/integration_test/mixer_server.go index fa129baf152..e36f04b484a 100644 --- a/src/envoy/mixer/integration_test/mixer_server.go +++ b/src/envoy/mixer/integration_test/mixer_server.go @@ -31,22 +31,22 @@ import ( ) type Handler struct { - bag attribute.MutableBag - count int + bag *attribute.MutableBag + ch chan int r_status rpc.Status } func newHandler() *Handler { return &Handler{ bag: nil, - count: 0, + ch: make(chan int, 1), r_status: rpc.Status{}, } } -func (h *Handler) run(bag attribute.MutableBag) rpc.Status { - h.bag = bag - h.count++ +func (h *Handler) run(bag *attribute.MutableBag) rpc.Status { + h.bag = attribute.CopyBag(bag) + h.ch <- 1 return h.r_status } @@ -61,19 +61,19 @@ type MixerServer struct { quota *Handler } -func (ts *MixerServer) Check(ctx context.Context, bag attribute.MutableBag, +func (ts *MixerServer) Check(ctx context.Context, bag *attribute.MutableBag, request *mixerpb.CheckRequest, response *mixerpb.CheckResponse) { response.RequestIndex = request.RequestIndex response.Result = ts.check.run(bag) } -func (ts *MixerServer) Report(ctx context.Context, bag attribute.MutableBag, +func (ts *MixerServer) Report(ctx context.Context, bag *attribute.MutableBag, request *mixerpb.ReportRequest, response *mixerpb.ReportResponse) { response.RequestIndex = request.RequestIndex response.Result = ts.report.run(bag) } -func (ts *MixerServer) Quota(ctx context.Context, bag attribute.MutableBag, +func (ts *MixerServer) Quota(ctx context.Context, bag *attribute.MutableBag, request *mixerpb.QuotaRequest, response *mixerpb.QuotaResponse) { response.RequestIndex = request.RequestIndex response.Result = ts.quota.run(bag) diff --git a/src/envoy/mixer/integration_test/mixer_test.go b/src/envoy/mixer/integration_test/mixer_test.go index 45f5e3835de..b8f382bd58c 100644 --- a/src/envoy/mixer/integration_test/mixer_test.go +++ b/src/envoy/mixer/integration_test/mixer_test.go @@ -257,14 +257,16 @@ const reportAttributesBackendFail = ` func verifyAttributes( s *TestSetup, tag string, check string, report string, t *testing.T) { - /* if err := s.mixer.check.ctx.curr.Verify(check); err != nil { - t.Fatalf("Failed to verify %s check: %v\n, Attributes: %+v", - tag, err, s.mixer.check.ctx.curr) - } - if err := s.mixer.report.ctx.curr.Verify(report); err != nil { - t.Fatalf("Failed to verify %s report: %v\n, Attributes: %+v", - tag, err, s.mixer.report.ctx.curr) - } */ + _ = <-s.mixer.check.ch + if err := Verify(s.mixer.check.bag, check); err != nil { + t.Fatalf("Failed to verify %s check: %v\n, Attributes: %+v", + tag, err, s.mixer.check.bag) + } + _ = <-s.mixer.report.ch + if err := Verify(s.mixer.report.bag, report); err != nil { + t.Fatalf("Failed to verify %s report: %v\n, Attributes: %+v", + tag, err, s.mixer.report.bag) + } } func TestMixer(t *testing.T) { diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl index 297f0c9017e..59fd8845691 100644 --- a/src/envoy/mixer/integration_test/repositories.bzl +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -6,7 +6,7 @@ def test_repositories(): go_mixer_repositories() go_repository( name = "com_github_istio_mixer", - commit = "0b2ef133ff6c912855cd059a8f98721ed51d0f93", + commit = "064001053b51f73adc3a80ff87ef41a15316c300", importpath = "github.com/istio/mixer", ) From a1864c47b668123726b8d9819afb8d649e54da3d Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Mon, 20 Mar 2017 11:57:17 -0700 Subject: [PATCH 7/8] Not to use mixer repository. --- WORKSPACE | 9 +- .../mixer/integration_test/repositories.bzl | 268 +++++++++++++++++- 2 files changed, 266 insertions(+), 11 deletions(-) diff --git a/WORKSPACE b/WORKSPACE index fee6b5d782d..be45a9c2765 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -110,10 +110,5 @@ git_repository( remote = "https://github.com/pubref/rules_protobuf", ) -local_repository( - name = "git_istio_mixer_bzl", - path = "/usr/local/google/home/qiwzhang/github/istio/mixer", -) - -load("//src/envoy/mixer/integration_test:repositories.bzl", "test_repositories") -test_repositories() \ No newline at end of file +load("//src/envoy/mixer/integration_test:repositories.bzl", "go_mixer_repositories") +go_mixer_repositories() \ No newline at end of file diff --git a/src/envoy/mixer/integration_test/repositories.bzl b/src/envoy/mixer/integration_test/repositories.bzl index 59fd8845691..7eec527fa39 100644 --- a/src/envoy/mixer/integration_test/repositories.bzl +++ b/src/envoy/mixer/integration_test/repositories.bzl @@ -1,9 +1,269 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_repositories", "new_go_repository", "go_repository") +load("@org_pubref_rules_protobuf//protobuf:rules.bzl", "proto_repositories") -load("@git_istio_mixer_bzl//:repositories.bzl", "go_mixer_repositories") -load("@io_bazel_rules_go//go:def.bzl", "go_repository") +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogo_proto_repositories") +load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cpp_proto_repositories") + +def go_istio_api_repositories(use_local=False): + ISTIO_API_BUILD_FILE = """ +# build protos from istio.io/api repo + +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") + +go_prefix("istio.io/api") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "mixer/v1", + importmap = { + "gogoproto/gogo.proto": "github.com/gogo/protobuf/gogoproto", + "google/rpc/status.proto": "github.com/googleapis/googleapis/google/rpc", + "google/protobuf/timestamp.proto": "github.com/gogo/protobuf/types", + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_gogo_protobuf", + "../../external/com_github_google_protobuf/src", + "../../external/com_github_googleapis_googleapis", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + "@com_github_googleapis_googleapis//:status_proto", + "@com_github_gogo_protobuf//gogoproto:go_default_library_protos", + ], + protos = [ + "mixer/v1/attributes.proto", + "mixer/v1/check.proto", + "mixer/v1/quota.proto", + "mixer/v1/report.proto", + "mixer/v1/service.proto", + ], + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = True, + deps = [ + "@com_github_gogo_protobuf//gogoproto:go_default_library", + "@com_github_gogo_protobuf//sortkeys:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + ], +) + +DESCRIPTOR_FILE_GROUP = [ + "mixer/v1/config/descriptor/attribute_descriptor.proto", + "mixer/v1/config/descriptor/label_descriptor.proto", + "mixer/v1/config/descriptor/log_entry_descriptor.proto", + "mixer/v1/config/descriptor/metric_descriptor.proto", + "mixer/v1/config/descriptor/monitored_resource_descriptor.proto", + "mixer/v1/config/descriptor/principal_descriptor.proto", + "mixer/v1/config/descriptor/quota_descriptor.proto", + "mixer/v1/config/descriptor/value_type.proto", +] + +gogoslick_proto_library( + name = "mixer/v1/config", + importmap = { + "google/protobuf/struct.proto": "github.com/gogo/protobuf/types", + "mixer/v1/config/descriptor/log_entry_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/metric_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/monitored_resource_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/principal_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + "mixer/v1/config/descriptor/quota_descriptor.proto": "istio.io/api/mixer/v1/config/descriptor", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = DESCRIPTOR_FILE_GROUP + [ + "@com_github_google_protobuf//:well_known_protos", + ], + protos = [ + "mixer/v1/config/cfg.proto", + ], + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = False, + deps = [ + ":mixer/v1/config/descriptor", + "@com_github_gogo_protobuf//sortkeys:go_default_library", + "@com_github_gogo_protobuf//types:go_default_library", + "@com_github_googleapis_googleapis//:google/rpc", + ], +) + +gogoslick_proto_library( + name = "mixer/v1/config/descriptor", + importmap = { + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + ], + protos = DESCRIPTOR_FILE_GROUP, + verbose = 0, + visibility = ["//visibility:public"], + with_grpc = False, + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + ], +) +""" + if use_local: + native.new_local_repository( + name = "com_github_istio_api", + build_file_content = ISTIO_API_BUILD_FILE, + path = "../api", + ) + else: + native.new_git_repository( + name = "com_github_istio_api", + build_file_content = ISTIO_API_BUILD_FILE, + commit = "2cb09827d7f09a6e88eac2c2249dcb45c5419f09", # Mar. 14, 2017 (no releases) + remote = "https://github.com/istio/api.git", + ) + +def go_googleapis_repositories(): + GOOGLEAPIS_BUILD_FILE = """ +package(default_visibility = ["//visibility:public"]) + +load("@io_bazel_rules_go//go:def.bzl", "go_prefix") +go_prefix("github.com/googleapis/googleapis") + +load("@org_pubref_rules_protobuf//gogo:rules.bzl", "gogoslick_proto_library") + +gogoslick_proto_library( + name = "google/rpc", + protos = [ + "google/rpc/code.proto", + "google/rpc/error_details.proto", + "google/rpc/status.proto", + ], + importmap = { + "google/protobuf/any.proto": "github.com/gogo/protobuf/types", + "google/protobuf/duration.proto": "github.com/gogo/protobuf/types", + }, + imports = [ + "../../external/com_github_google_protobuf/src", + ], + inputs = [ + "@com_github_google_protobuf//:well_known_protos", + ], + deps = [ + "@com_github_gogo_protobuf//types:go_default_library", + ], + verbose = 0, +) + +load("@org_pubref_rules_protobuf//cpp:rules.bzl", "cc_proto_library") + +cc_proto_library( + name = "cc_status_proto", + protos = [ + "google/rpc/status.proto", + ], + imports = [ + "../../external/com_github_google_protobuf/src", + ], + verbose = 0, +) + +filegroup( + name = "status_proto", + srcs = [ "google/rpc/status.proto" ], +) + +filegroup( + name = "code_proto", + srcs = [ "google/rpc/code.proto" ], +) +""" + native.new_git_repository( + name = "com_github_googleapis_googleapis", + build_file_content = GOOGLEAPIS_BUILD_FILE, + commit = "13ac2436c5e3d568bd0e938f6ed58b77a48aba15", # Oct 21, 2016 (only release pre-dates sha) + remote = "https://github.com/googleapis/googleapis.git", + ) + +def go_mixer_repositories(use_local_api=False): + go_istio_api_repositories(use_local_api) + go_googleapis_repositories() + + go_repositories() + proto_repositories() + + gogo_proto_repositories() + + new_go_repository( + name = "com_github_golang_glog", + commit = "23def4e6c14b4da8ac2ed8007337bc5eb5007998", # Jan 26, 2016 (no releases) + importpath = "github.com/golang/glog", + ) + + new_go_repository( + name = "com_github_ghodss_yaml", + commit = "04f313413ffd65ce25f2541bfd2b2ceec5c0908c", # Dec 6, 2016 (no releases) + importpath = "github.com/ghodss/yaml", + ) + + new_go_repository( + name = "in_gopkg_yaml_v2", + commit = "14227de293ca979cf205cd88769fe71ed96a97e2", # Jan 24, 2017 (no releases) + importpath = "gopkg.in/yaml.v2", + ) + + new_go_repository( + name = "com_github_golang_protobuf", + commit = "8ee79997227bf9b34611aee7946ae64735e6fd93", # Nov 16, 2016 (no releases) + importpath = "github.com/golang/protobuf", + ) + + new_go_repository( + name = "org_golang_google_grpc", + commit = "708a7f9f3283aa2d4f6132d287d78683babe55c8", # Dec 5, 2016 (v1.0.5) + importpath = "google.golang.org/grpc", + ) + + new_go_repository( + name = "com_github_spf13_cobra", + commit = "35136c09d8da66b901337c6e86fd8e88a1a255bd", # Jan 30, 2017 (no releases) + importpath = "github.com/spf13/cobra", + ) + + new_go_repository( + name = "com_github_spf13_pflag", + commit = "9ff6c6923cfffbcd502984b8e0c80539a94968b7", # Jan 30, 2017 (no releases) + importpath = "github.com/spf13/pflag", + ) + + new_go_repository( + name = "com_github_hashicorp_go_multierror", + commit = "ed905158d87462226a13fe39ddf685ea65f1c11f", # Dec 16, 2016 (no releases) + importpath = "github.com/hashicorp/go-multierror", + ) + + new_go_repository( + name = "com_github_hashicorp_errwrap", + commit = "7554cd9344cec97297fa6649b055a8c98c2a1e55", # Oct 27, 2014 (no releases) + importpath = "github.com/hashicorp/errwrap", + ) + + new_go_repository( + name = "com_github_opentracing_opentracing_go", + commit = "0c3154a3c2ce79d3271985848659870599dfb77c", # Sep 26, 2016 (v1.0.0) + importpath = "github.com/opentracing/opentracing-go", + ) + + new_go_repository( + name = "com_github_opentracing_basictracer", + commit = "1b32af207119a14b1b231d451df3ed04a72efebf", # Sep 29, 2016 (no releases) + importpath = "github.com/opentracing/basictracer-go", + ) -def test_repositories(): - go_mixer_repositories() go_repository( name = "com_github_istio_mixer", commit = "064001053b51f73adc3a80ff87ef41a15316c300", From 950722557834f76b3f7d70c2b779b4d8c120f4ae Mon Sep 17 00:00:00 2001 From: Wayne Zhang Date: Mon, 20 Mar 2017 12:02:54 -0700 Subject: [PATCH 8/8] Add return line at the end of WORKSPACE. --- WORKSPACE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WORKSPACE b/WORKSPACE index be45a9c2765..4bc7137304c 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -111,4 +111,4 @@ git_repository( ) load("//src/envoy/mixer/integration_test:repositories.bzl", "go_mixer_repositories") -go_mixer_repositories() \ No newline at end of file +go_mixer_repositories()