istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tests/integration/pilot/gateway_conformance_test.go (about)

     1  //go:build integ
     2  // +build integ
     3  
     4  // Copyright Istio Authors
     5  //
     6  // Licensed under the Apache License, Version 2.0 (the "License");
     7  // you may not use this file except in compliance with the License.
     8  // You may obtain a copy of the License at
     9  //
    10  //     http://www.apache.org/licenses/LICENSE-2.0
    11  //
    12  // Unless required by applicable law or agreed to in writing, software
    13  // distributed under the License is distributed on an "AS IS" BASIS,
    14  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15  // See the License for the specific language governing permissions and
    16  // limitations under the License.
    17  
    18  package pilot
    19  
    20  import (
    21  	"io/fs"
    22  	"os"
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	k8ssets "k8s.io/apimachinery/pkg/util/sets" //nolint: depguard
    27  	"sigs.k8s.io/controller-runtime/pkg/client"
    28  	v1 "sigs.k8s.io/gateway-api/apis/v1"
    29  	"sigs.k8s.io/gateway-api/conformance"
    30  	confv1 "sigs.k8s.io/gateway-api/conformance/apis/v1"
    31  	"sigs.k8s.io/gateway-api/conformance/tests"
    32  	"sigs.k8s.io/gateway-api/conformance/utils/suite"
    33  	"sigs.k8s.io/gateway-api/pkg/features"
    34  	"sigs.k8s.io/yaml"
    35  
    36  	"istio.io/istio/pilot/pkg/config/kube/gateway"
    37  	"istio.io/istio/pkg/kube"
    38  	"istio.io/istio/pkg/maps"
    39  	"istio.io/istio/pkg/test/env"
    40  	"istio.io/istio/pkg/test/framework"
    41  	"istio.io/istio/pkg/test/framework/components/crd"
    42  	"istio.io/istio/pkg/test/framework/components/namespace"
    43  	"istio.io/istio/pkg/test/prow"
    44  	"istio.io/istio/pkg/test/scopes"
    45  	"istio.io/istio/pkg/test/util/assert"
    46  )
    47  
    48  // GatewayConformanceInputs defines inputs to the gateway conformance test.
    49  // The upstream build requires using `testing.T` types, which we cannot pass using our framework.
    50  // To workaround this, we set up the inputs it TestMain.
    51  type GatewayConformanceInputs struct {
    52  	Client  kube.CLIClient
    53  	Cleanup bool
    54  }
    55  
    56  var gatewayConformanceInputs GatewayConformanceInputs
    57  
    58  // defined in sigs.k8s.io/gateway-api/conformance/base/manifests.yaml
    59  var conformanceNamespaces = []string{
    60  	"gateway-conformance-infra",
    61  	"gateway-conformance-mesh",
    62  	"gateway-conformance-mesh-consumer",
    63  	"gateway-conformance-app-backend",
    64  	"gateway-conformance-web-backend",
    65  }
    66  
    67  var skippedTests = map[string]string{}
    68  
    69  func TestGatewayConformance(t *testing.T) {
    70  	framework.
    71  		NewTest(t).
    72  		Run(func(ctx framework.TestContext) {
    73  			crd.DeployGatewayAPIOrSkip(ctx)
    74  
    75  			// Precreate the GatewayConformance namespaces, and apply the Image Pull Secret to them.
    76  			if ctx.Settings().Image.PullSecret != "" {
    77  				for _, ns := range conformanceNamespaces {
    78  					namespace.Claim(ctx, namespace.Config{
    79  						Prefix: ns,
    80  						Inject: false,
    81  					})
    82  				}
    83  			}
    84  
    85  			mapper, _ := gatewayConformanceInputs.Client.UtilFactory().ToRESTMapper()
    86  			c, err := client.New(gatewayConformanceInputs.Client.RESTConfig(), client.Options{
    87  				Scheme: kube.IstioScheme,
    88  				Mapper: mapper,
    89  			})
    90  			if err != nil {
    91  				t.Fatal(err)
    92  			}
    93  
    94  			supportedFeatures := gateway.SupportedFeatures.Clone().
    95  				Delete(features.SupportMeshClusterIPMatching) // https://github.com/istio/istio/issues/44702
    96  			if ctx.Settings().GatewayConformanceStandardOnly {
    97  				supportedFeatures = k8ssets.New[features.SupportedFeature]().
    98  					Insert(features.GatewayExtendedFeatures.UnsortedList()...).
    99  					Insert(features.ReferenceGrantCoreFeatures.UnsortedList()...).
   100  					Insert(features.HTTPRouteCoreFeatures.UnsortedList()...).
   101  					Insert(features.HTTPRouteExtendedFeatures.UnsortedList()...).
   102  					Insert(features.MeshCoreFeatures.UnsortedList()...).
   103  					Insert(features.GRPCRouteCoreFeatures.UnsortedList()...)
   104  			}
   105  			hostnameType := v1.AddressType("Hostname")
   106  			istioVersion, _ := env.ReadVersion()
   107  			opts := suite.ConformanceOptions{
   108  				Client:                   c,
   109  				Clientset:                gatewayConformanceInputs.Client.Kube(),
   110  				RestConfig:               gatewayConformanceInputs.Client.RESTConfig(),
   111  				GatewayClassName:         "istio",
   112  				Debug:                    scopes.Framework.DebugEnabled(),
   113  				CleanupBaseResources:     gatewayConformanceInputs.Cleanup,
   114  				ManifestFS:               []fs.FS{&conformance.Manifests},
   115  				SupportedFeatures:        supportedFeatures,
   116  				SkipTests:                maps.Keys(skippedTests),
   117  				UsableNetworkAddresses:   []v1.GatewayAddress{{Value: "infra-backend-v1.gateway-conformance-infra.svc.cluster.local", Type: &hostnameType}},
   118  				UnusableNetworkAddresses: []v1.GatewayAddress{{Value: "foo", Type: &hostnameType}},
   119  				ConformanceProfiles: k8ssets.New(
   120  					suite.GatewayHTTPConformanceProfileName,
   121  					suite.GatewayTLSConformanceProfileName,
   122  					suite.GatewayGRPCConformanceProfileName,
   123  					suite.MeshHTTPConformanceProfileName,
   124  				),
   125  				Implementation: confv1.Implementation{
   126  					Organization: "istio",
   127  					Project:      "istio",
   128  					URL:          "https://istio.io/",
   129  					Version:      istioVersion,
   130  					Contact:      []string{"@istio/maintainers"},
   131  				},
   132  				TimeoutConfig: ctx.Settings().GatewayConformanceTimeoutConfig,
   133  			}
   134  			if rev := ctx.Settings().Revisions.Default(); rev != "" {
   135  				opts.NamespaceLabels = map[string]string{
   136  					"istio.io/rev": rev,
   137  				}
   138  			} else {
   139  				opts.NamespaceLabels = map[string]string{
   140  					"istio-injection": "enabled",
   141  				}
   142  			}
   143  			ctx.Cleanup(func() {
   144  				if !ctx.Failed() {
   145  					return
   146  				}
   147  				if ctx.Settings().CIMode {
   148  					for _, ns := range conformanceNamespaces {
   149  						namespace.Dump(ctx, ns)
   150  					}
   151  				}
   152  			})
   153  
   154  			csuite, err := suite.NewConformanceTestSuite(opts)
   155  			assert.NoError(t, err)
   156  			csuite.Setup(t, tests.ConformanceTests)
   157  			assert.NoError(t, csuite.Run(t, tests.ConformanceTests))
   158  			report, err := csuite.Report()
   159  			assert.NoError(t, err)
   160  			reportb, err := yaml.Marshal(report)
   161  			assert.NoError(t, err)
   162  			fp := filepath.Join(ctx.Settings().BaseDir, "conformance.yaml")
   163  			t.Logf("writing conformance test to %v (%v)", fp, prow.ArtifactsURL(fp))
   164  			assert.NoError(t, os.WriteFile(fp, reportb, 0o644))
   165  		})
   166  }