Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pkg/test/framework/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ func TestHTTP(t *testing.T) {

be := b.EndpointsForProtocol(model.ProtocolHTTP)[0]
result := a.CallOrFail(be, components.AppCallOptions{}, t)[0]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably don't worry about changing this file. I believe it's going away anyway.

@ozevren?

if !result.IsOK() {
t.Fatalf("HTTP Request unsuccessful: %s", result.Body)
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/test/framework/components/apps/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ type Config struct {
AppParams []AppParam
}

func (c Config) fillInDefaults(ctx resource.Context) (err error) {
func (c *Config) fillInDefaults(ctx resource.Context) (err error) {
if c.Galley == nil {
return errors.New("galley must not be nil")
}
Expand Down
21 changes: 7 additions & 14 deletions pkg/test/framework/components/apps/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -322,9 +322,11 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) {

var err error

// Wait for the pods to transition to running.
if c.namespace, err = namespace.New(ctx, "apps", true); err != nil {
return nil, err
c.namespace = cfg.Namespace
if c.namespace == nil {
if c.namespace, err = namespace.New(ctx, "apps", true); err != nil {
return nil, err
}
}

params := cfg.AppParams
Expand Down Expand Up @@ -663,19 +665,9 @@ func (a *kubeApp) Call(e AppEndpoint, opts AppCallOptions) ([]*echo.ParsedRespon
if err != nil {
return nil, err
}

if len(resp) != 1 {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should leave the check for len here. Everything else we can remove completely.

if len(resp) != opts.Count {
return nil, fmt.Errorf("unexpected number of responses: %d", len(resp))
}
if !resp[0].IsOK() {
return nil, fmt.Errorf("unexpected response status code: %s", resp[0].Code)
}
if resp[0].Host != dstServiceName {
return nil, fmt.Errorf("unexpected host: %s", resp[0].Host)
}
if resp[0].Port != strconv.Itoa(dst.networkEndpoint.ServicePort.Port) {
return nil, fmt.Errorf("unexpected port: %s", resp[0].Port)
}

return resp, nil
}
Expand All @@ -685,6 +677,7 @@ func (a *kubeApp) CallOrFail(e AppEndpoint, opts AppCallOptions, t testing.TB) [
if err != nil {
t.Fatal(err)
}

return r
}

Expand Down
12 changes: 2 additions & 10 deletions pkg/test/framework/components/apps/native.go
Original file line number Diff line number Diff line change
Expand Up @@ -388,18 +388,9 @@ func (a *nativeApp) Call(e AppEndpoint, opts AppCallOptions) ([]*echo.ParsedResp
return nil, err
}

if len(resp) != 1 {
if len(resp) != opts.Count {
return nil, fmt.Errorf("unexpected number of responses: %d", len(resp))
}
if !resp[0].IsOK() {
return nil, fmt.Errorf("unexpected response status code: %s", resp[0].Code)
}
if resp[0].Host != dstHost {
return nil, fmt.Errorf("unexpected host: %s", resp[0].Host)
}
if resp[0].Port != strconv.Itoa(dst.port.ApplicationPort) {
return nil, fmt.Errorf("unexpected port: %s", resp[0].Port)
}

return resp, nil
}
Expand All @@ -409,6 +400,7 @@ func (a *nativeApp) CallOrFail(e AppEndpoint, opts AppCallOptions, t testing.TB)
if err != nil {
t.Fatal(err)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd imagine there could be a test where if a request fails due to some reason, e.g. network, then the test may want to try again, so maybe let the caller decide to stop the test if they want to, and change the function name to something like GetResponseOrError or CallOrError and return ([]*echo.ParsedRepsonse, error)?

}

return r
}

Expand Down
5 changes: 1 addition & 4 deletions pkg/test/framework/components/apps/native_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@ func TestNative(t *testing.T) {
b := all.GetAppOrFail("b", t)

be := b.EndpointsForProtocol(model.ProtocolHTTP)[0]
responses := a.CallOrFail(be, apps.AppCallOptions{}, t)
if !responses[0].IsOK() {
t.Fatalf("failed sending request from a to b: %+v", responses)
}
_ = a.CallOrFail(be, apps.AppCallOptions{}, t)
}

func TestMain(m *testing.M) {
Expand Down
2 changes: 1 addition & 1 deletion pkg/test/framework/components/deployment/kube.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func newKube(ctx resource.Context, cfg Config) (Instance, error) {
scopes.Framework.Errorf("Error deploying %q: %v", cfg.Name, err)
scopes.CI.Errorf("=== FAILED: Deployment %q ===", cfg.Name)
} else {
scopes.CI.Errorf("=== SUCCEEDED: Deployment %q ===", cfg.Name)
scopes.CI.Infof("=== SUCCEEDED: Deployment %q ===", cfg.Name)
}
}()

Expand Down
2 changes: 1 addition & 1 deletion tests/integration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ func mySetup(ctx framework.SuiteContext) error {
### Helm Values Overrides

If your tests require special Helm values flags, you can specify your Helm values via additional
for Kubernetes environments. See [mtls_healthcheck_test.go](tests/integration/security/healthcheck/mtls_healthcheck_test.go) for example.
for Kubernetes environments. See [mtls_healthcheck_test.go](security/healthcheck/mtls_healthcheck_test.go) for example.


### Command-Line Flags
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2019 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 allowany

import (
"testing"

"istio.io/istio/pkg/test/framework"
"istio.io/istio/pkg/test/framework/components/environment"
"istio.io/istio/pkg/test/framework/components/istio"
"istio.io/istio/tests/integration/pilot/outboundtrafficpolicy"
)

func TestMain(m *testing.M) {
var ist istio.Instance
framework.NewSuite("outbound_traffic_policy_allow_any", m).
RequireEnvironment(environment.Kube).
Setup(istio.SetupOnKube(&ist, setupConfig)).
Run()
}

func setupConfig(cfg *istio.Config) {
if cfg == nil {
return
}
cfg.Values["global.outboundTrafficPolicy.mode"] = "ALLOW_ANY"
cfg.Values["pilot.env.PILOT_ENABLE_FALLTHROUGH_ROUTE"] = "true"
}

func TestOutboundTrafficPolicyAllowAny(t *testing.T) {
expected := map[string][]string{
"http": {"200"},
"https": {"200"},
}
outboundtrafficpolicy.RunExternalRequestTest(expected, t)
}
150 changes: 150 additions & 0 deletions tests/integration/pilot/outboundtrafficpolicy/helper.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
package outboundtrafficpolicy

import (
"bytes"
"html/template"
"reflect"
"testing"

"istio.io/istio/pkg/test/framework"
"istio.io/istio/pkg/test/framework/components/apps"
"istio.io/istio/pkg/test/framework/components/environment"
"istio.io/istio/pkg/test/framework/components/galley"
"istio.io/istio/pkg/test/framework/components/namespace"
"istio.io/istio/pkg/test/framework/components/pilot"
)

const (
IstioSystemScope = `
`
ServiceEntry = `
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: https-service
spec:
hosts:
- istio.io
location: MESH_EXTERNAL
ports:
- name: https
number: 90
protocol: HTTPS
resolution: DNS
---
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: http
spec:
hosts:
- istio.io
location: MESH_EXTERNAL
ports:
- name: http
number: 80
protocol: HTTP
resolution: DNS
`
SidecarScope = `
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: restrict-to-service-entry-namespace
spec:
egress:
- hosts:
- "{{.ImportNamespace}}/*"
- "istio-system/*"
`
)

// We want to test "external" traffic. To do this without actually hitting an external endpoint,
// we can import only the service namespace, so the apps are not known
func createSidecarScope(t *testing.T, appsNamespace namespace.Instance, serviceNamespace namespace.Instance, g galley.Instance) {
tmpl, err := template.New("SidecarScope").Parse(SidecarScope)
if err != nil {
t.Errorf("failed to create template: %v", err)
}

var buf bytes.Buffer
if err := tmpl.Execute(&buf, map[string]string{"ImportNamespace": serviceNamespace.Name()}); err != nil {
t.Errorf("failed to create template: %v", err)
}
if err := g.ApplyConfig(appsNamespace, buf.String()); err != nil {
t.Errorf("failed to apply service entries: %v", err)
}
}

// TODO support native environment. Blocked by #13177 because the listeners for native use static
// routes and this test relies on the dynamic routes sent through pilot to allow external traffic.

// Expected is a map of protocol -> expected response codes
func RunExternalRequestTest(expected map[string][]string, t *testing.T) {
framework.
NewTest(t).
RequiresEnvironment(environment.Kube).
Run(func(ctx framework.TestContext) {
g := galley.NewOrFail(t, ctx, galley.Config{})
p := pilot.NewOrFail(t, ctx, pilot.Config{Galley: g})

appsNamespace := namespace.NewOrFail(t, ctx, "app", true)
serviceNamespace := namespace.NewOrFail(t, ctx, "service", true)

createSidecarScope(t, appsNamespace, serviceNamespace, g)

// External traffic should work even if we have service entries on the same ports
if err := g.ApplyConfig(serviceNamespace, ServiceEntry); err != nil {
t.Errorf("failed to apply service entries: %v", err)
}

instance := apps.NewOrFail(t, ctx, apps.Config{
Namespace: appsNamespace,
Pilot: p,
Galley: g,
AppParams: []apps.AppParam{
{Name: "client"},
{Name: "destination"},
},
})

client := instance.GetAppOrFail("client", t).(apps.KubeApp)
dest := instance.GetAppOrFail("destination", t).(apps.KubeApp)

cases := []struct {
name string
protocol string
port int
}{
{
"HTTP Traffic",
"http",
80,
},
{
"HTTPS Traffic",
"https",
90,
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
if tc.protocol == "https" {
t.Skip("https is currently not supported until #13386 is fixed")
}
ep := dest.EndpointForPort(tc.port)
resp, err := client.Call(ep, apps.AppCallOptions{})
if err != nil {
t.Errorf("call failed: %v", err)
}
codes := make([]string, 0, len(resp))
for _, r := range resp {
codes = append(codes, r.Code)
}
if !reflect.DeepEqual(codes, expected[tc.protocol]) {
t.Errorf("got codes %v, expected %v", codes, expected[tc.protocol])
}
})
}
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// Copyright 2019 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 registryonly

import (
"testing"

"istio.io/istio/pkg/test/framework"
"istio.io/istio/pkg/test/framework/components/environment"
"istio.io/istio/pkg/test/framework/components/istio"
"istio.io/istio/tests/integration/pilot/outboundtrafficpolicy"
)

func TestMain(m *testing.M) {
var ist istio.Instance
framework.NewSuite("outbound_traffic_policy_registry_only", m).
RequireEnvironment(environment.Kube).
Setup(istio.SetupOnKube(&ist, setupConfig)).
Run()
}

func setupConfig(cfg *istio.Config) {
if cfg == nil {
return
}
cfg.Values["global.outboundTrafficPolicy.mode"] = "REGISTRY_ONLY"
cfg.Values["pilot.env.PILOT_ENABLE_FALLTHROUGH_ROUTE"] = "true"
}

func TestOutboundTrafficPolicyRegistryOnly(t *testing.T) {
expected := map[string][]string{
"http": {"502"}, // HTTP will return an error code
"https": {}, // HTTPS will direct to blackhole cluster, giving no response
}
outboundtrafficpolicy.RunExternalRequestTest(expected, t)
}