istio.io/istio@v0.0.0-20240520182934-d79c90f27776/pkg/test/framework/resource/settings.go (about) 1 // Copyright Istio Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package resource 16 17 import ( 18 "fmt" 19 "os" 20 "path" 21 "strings" 22 23 "github.com/google/uuid" 24 "gopkg.in/yaml.v3" 25 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 26 gwConformanceConfig "sigs.k8s.io/gateway-api/conformance/utils/config" 27 28 "istio.io/istio/pkg/test" 29 "istio.io/istio/pkg/test/framework/label" 30 "istio.io/istio/pkg/util/sets" 31 ) 32 33 const ( 34 // maxTestIDLength is the maximum length allowed for testID. 35 maxTestIDLength = 30 36 ) 37 38 // ImageSettings for container images. 39 type ImageSettings struct { 40 // Hub value to use in Helm templates 41 Hub string 42 43 // Tag value to use in Helm templates 44 Tag string 45 46 // Variant value to use in Helm templates 47 Variant string 48 49 // Image pull policy to use for deployments. If not specified, the defaults of each deployment will be used. 50 PullPolicy string 51 52 // PullSecret path to a file containing a k8s secret in yaml so test pods can pull from protected registries. 53 PullSecret string 54 } 55 56 func (s *ImageSettings) PullSecretName() (string, error) { 57 if s.PullSecret == "" { 58 return "", nil 59 } 60 data, err := os.ReadFile(s.PullSecret) 61 if err != nil { 62 return "", err 63 } 64 secret := unstructured.Unstructured{Object: map[string]any{}} 65 if err := yaml.Unmarshal(data, secret.Object); err != nil { 66 return "", err 67 } 68 return secret.GetName(), nil 69 } 70 71 func (s *ImageSettings) PullSecretNameOrFail(t test.Failer) string { 72 t.Helper() 73 out, err := s.PullSecretName() 74 if err != nil { 75 t.Fatal(err) 76 } 77 return out 78 } 79 80 // Settings is the set of arguments to the test driver. 81 type Settings struct { 82 // Name of the test 83 TestID string 84 85 RunID uuid.UUID 86 87 // Do not cleanup the resources after the test run. 88 NoCleanup bool 89 90 // Indicates that the tests are running in CI Mode 91 CIMode bool 92 93 // Should the tests fail if usage of deprecated stuff (e.g. Envoy flags) is detected 94 FailOnDeprecation bool 95 96 // Local working directory root for creating temporary directories / files in. If left empty, 97 // os.TempDir() will be used. 98 BaseDir string 99 100 // The number of times to retry failed tests. 101 // This should not be depended on as a primary means for reducing test flakes. 102 Retries int 103 104 // If enabled, namespaces will be reused rather than created with dynamic names each time. 105 // This is useful when combined with NoCleanup, to allow quickly iterating on tests. 106 StableNamespaces bool 107 108 // The label selector that the user has specified. 109 SelectorString string 110 111 // The regex specifying which tests to skip. This follows inverted semantics of golang's 112 // -test.run flag, which only supports positive match. If an entire package is meant to be 113 // excluded, it can be filtered with `go list` and explicitly passing the list of desired 114 // packages. For example: `go test $(go list ./... | grep -v bad-package)`. 115 SkipString ArrayFlags 116 SkipMatcher *Matcher 117 118 // SkipWorkloadClasses can be used to skip deploying special workload types like TPROXY, VMs, etc. 119 SkipWorkloadClasses ArrayFlags 120 121 // OnlyWorkloadClasses can be used to only deploy specific workload types like TPROXY, VMs, etc. 122 OnlyWorkloadClasses ArrayFlags 123 124 // The label selector, in parsed form. 125 Selector label.Selector 126 127 // EnvironmentFactory allows caller to override the environment creation. If nil, a default is used based 128 // on the known environment names. 129 EnvironmentFactory EnvironmentFactory 130 131 // Deprecated: prefer to use `--istio.test.revisions=<revision name>`. 132 // The revision label on a namespace for injection webhook. 133 // If set to XXX, all the namespaces created with istio-injection=enabled will be replaced with istio.io/rev=XXX. 134 Revision string 135 136 // Skip VM related parts for all the tests. 137 SkipVM bool 138 139 // Skip TProxy related parts for all the tests. 140 SkipTProxy bool 141 142 // Ambient mesh is being used 143 Ambient bool 144 145 // Use ambient instead of sidecars 146 AmbientEverywhere bool 147 148 // Compatibility determines whether we should transparently deploy echo workloads attached to each revision 149 // specified in `Revisions` when creating echo instances. Used primarily for compatibility testing between revisions 150 // on different control plane versions. 151 Compatibility bool 152 153 // Revisions maps the Istio revisions that are available to each cluster to their corresponding versions. 154 // This flag must be used with --istio.test.kube.deploy=false with the versions pre-installed. 155 // This flag should be passed in as comma-separated values, such as "rev-a=1.7.3,rev-b=1.8.2,rev-c=1.9.0", and the test framework will 156 // spin up pods pointing to these revisions for each echo instance and skip tests accordingly. 157 // To configure it so that an Istio revision is on the latest version simply list the revision name without the version (i.e. "rev-a,rev-b") 158 // If using this flag with --istio.test.revision, this flag will take precedence. 159 Revisions RevVerMap 160 161 // Image settings 162 Image ImageSettings 163 164 // EchoImage is the app image to be used by echo deployments. 165 EchoImage string 166 167 // CustomGRPCEchoImage if specified will run an extra container in the echo Pods responsible for gRPC ports 168 CustomGRPCEchoImage string 169 170 // MaxDumps is the maximum number of full test dumps that are allowed to occur within a test suite. 171 MaxDumps uint64 172 173 // EnableDualStack indicates the test should have dual stack enabled or not. 174 EnableDualStack bool 175 176 // Helm repo to be used for tests 177 HelmRepo string 178 179 DisableDefaultExternalServiceConnectivity bool 180 181 PeerMetadataDiscovery bool 182 183 // GatewayConformanceStandardOnly indicates that only the standard gateway conformance tests should be run. 184 GatewayConformanceStandardOnly bool 185 186 GatewayConformanceTimeoutConfig gwConformanceConfig.TimeoutConfig 187 188 // OpenShift indicates the tests run in an OpenShift platform rather than in plain Kubernetes. 189 OpenShift bool 190 } 191 192 // SkipVMs changes the skip settings at runtime 193 func (s *Settings) SkipVMs() { 194 s.SkipVM = true 195 s.SkipWorkloadClasses = append(s.SkipWorkloadClasses, "vm") 196 } 197 198 // Skip checks whether a given class is skipped 199 func (s *Settings) Skip(class string) bool { 200 if s.SkipWorkloadClassesAsSet().Contains(class) { 201 return true 202 } 203 if len(s.OnlyWorkloadClasses) > 0 && !s.OnlyWorkloadClassesAsSet().Contains(class) { 204 return true 205 } 206 return false 207 } 208 209 func (s *Settings) SkipWorkloadClassesAsSet() sets.String { 210 return sets.New[string](s.SkipWorkloadClasses...) 211 } 212 213 func (s *Settings) OnlyWorkloadClassesAsSet() sets.String { 214 return sets.New[string](s.OnlyWorkloadClasses...) 215 } 216 217 // RunDir is the name of the dir to output, for this particular run. 218 func (s *Settings) RunDir() string { 219 u := strings.Replace(s.RunID.String(), "-", "", -1) 220 t := strings.Replace(s.TestID, "_", "-", -1) 221 // We want at least 6 characters of uuid padding 222 padding := maxTestIDLength - len(t) 223 if padding < 0 { 224 padding = 0 225 } 226 n := fmt.Sprintf("%s-%s", t, u[0:padding]) 227 228 return path.Join(s.BaseDir, n) 229 } 230 231 // Clone settings 232 func (s *Settings) Clone() *Settings { 233 cl := *s 234 return &cl 235 } 236 237 // DefaultSettings returns a default settings instance. 238 func DefaultSettings() *Settings { 239 return &Settings{ 240 RunID: uuid.New(), 241 MaxDumps: 10, 242 } 243 } 244 245 // String implements fmt.Stringer 246 func (s *Settings) String() string { 247 result := "" 248 249 result += fmt.Sprintf("TestID: %s\n", s.TestID) 250 result += fmt.Sprintf("RunID: %s\n", s.RunID.String()) 251 result += fmt.Sprintf("NoCleanup: %v\n", s.NoCleanup) 252 result += fmt.Sprintf("BaseDir: %s\n", s.BaseDir) 253 result += fmt.Sprintf("Selector: %v\n", s.Selector) 254 result += fmt.Sprintf("FailOnDeprecation: %v\n", s.FailOnDeprecation) 255 result += fmt.Sprintf("CIMode: %v\n", s.CIMode) 256 result += fmt.Sprintf("Retries: %v\n", s.Retries) 257 result += fmt.Sprintf("StableNamespaces: %v\n", s.StableNamespaces) 258 result += fmt.Sprintf("Revision: %v\n", s.Revision) 259 result += fmt.Sprintf("SkipWorkloads %v\n", s.SkipWorkloadClasses) 260 result += fmt.Sprintf("Compatibility: %v\n", s.Compatibility) 261 result += fmt.Sprintf("Revisions: %v\n", s.Revisions.String()) 262 result += fmt.Sprintf("Hub: %s\n", s.Image.Hub) 263 result += fmt.Sprintf("Tag: %s\n", s.Image.Tag) 264 result += fmt.Sprintf("Variant: %s\n", s.Image.Variant) 265 result += fmt.Sprintf("PullPolicy: %s\n", s.Image.PullPolicy) 266 result += fmt.Sprintf("PullSecret: %s\n", s.Image.PullSecret) 267 result += fmt.Sprintf("MaxDumps: %d\n", s.MaxDumps) 268 result += fmt.Sprintf("HelmRepo: %v\n", s.HelmRepo) 269 result += fmt.Sprintf("GatewayConformanceStandardOnly: %v\n", s.GatewayConformanceStandardOnly) 270 return result 271 } 272 273 type ArrayFlags []string 274 275 func (i *ArrayFlags) String() string { 276 return fmt.Sprint([]string(*i)) 277 } 278 279 func (i *ArrayFlags) Set(value string) error { 280 *i = append(*i, value) 281 return nil 282 }