blob: c0804a4c56f74164d6ee65ffc02859dfefedffe6 [file] [log] [blame]
// Copyright 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 resource
import (
"fmt"
"os"
"path"
"strings"
)
import (
"github.com/google/uuid"
"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
)
import (
"github.com/apache/dubbo-go-pixiu/pkg/test"
"github.com/apache/dubbo-go-pixiu/pkg/test/framework/label"
"github.com/apache/dubbo-go-pixiu/pkg/util/sets"
)
const (
// maxTestIDLength is the maximum length allowed for testID.
maxTestIDLength = 30
)
// ImageSettings for container images.
type ImageSettings struct {
// Hub value to use in Helm templates
Hub string
// Tag value to use in Helm templates
Tag string
// Image pull policy to use for deployments. If not specified, the defaults of each deployment will be used.
PullPolicy string
// PullSecret path to a file containing a k8s secret in yaml so test pods can pull from protected registries.
PullSecret string
}
func (s *ImageSettings) PullSecretName() (string, error) {
if s.PullSecret == "" {
return "", nil
}
data, err := os.ReadFile(s.PullSecret)
if err != nil {
return "", err
}
secret := unstructured.Unstructured{Object: map[string]interface{}{}}
if err := yaml.Unmarshal(data, secret.Object); err != nil {
return "", err
}
return secret.GetName(), nil
}
func (s *ImageSettings) PullSecretNameOrFail(t test.Failer) string {
t.Helper()
out, err := s.PullSecretName()
if err != nil {
t.Fatal(err)
}
return out
}
// Settings is the set of arguments to the test driver.
type Settings struct {
// Name of the test
TestID string
RunID uuid.UUID
// Do not cleanup the resources after the test run.
NoCleanup bool
// Indicates that the tests are running in CI Mode
CIMode bool
// Should the tests fail if usage of deprecated stuff (e.g. Envoy flags) is detected
FailOnDeprecation bool
// Local working directory root for creating temporary directories / files in. If left empty,
// os.TempDir() will be used.
BaseDir string
// The number of times to retry failed tests.
// This should not be depended on as a primary means for reducing test flakes.
Retries int
// If enabled, namespaces will be reused rather than created with dynamic names each time.
// This is useful when combined with NoCleanup, to allow quickly iterating on tests.
StableNamespaces bool
// The label selector that the user has specified.
SelectorString string
// The regex specifying which tests to skip. This follows inverted semantics of golang's
// -test.run flag, which only supports positive match. If an entire package is meant to be
// excluded, it can be filtered with `go list` and explicitly passing the list of desired
// packages. For example: `go test $(go list ./... | grep -v bad-package)`.
SkipString ArrayFlags
SkipMatcher *Matcher
// SkipWorkloadClasses can be used to skip deploying special workload types like TPROXY, VMs, etc.
SkipWorkloadClasses ArrayFlags
// The label selector, in parsed form.
Selector label.Selector
// EnvironmentFactory allows caller to override the environment creation. If nil, a default is used based
// on the known environment names.
EnvironmentFactory EnvironmentFactory
// Deprecated: prefer to use `--istio.test.revisions=<revision name>`.
// The revision label on a namespace for injection webhook.
// If set to XXX, all the namespaces created with istio-injection=enabled will be replaced with istio.io/rev=XXX.
Revision string
// Skip VM related parts for all the tests.
SkipVM bool
// Skip Delta XDS related parts for all the tests.
SkipDelta bool
// Skip TProxy related parts for all the tests.
SkipTProxy bool
// Compatibility determines whether we should transparently deploy echo workloads attached to each revision
// specified in `Revisions` when creating echo instances. Used primarily for compatibility testing between revisions
// on different control plane versions.
Compatibility bool
// Revisions maps the Istio revisions that are available to each cluster to their corresponding versions.
// This flag must be used with --istio.test.kube.deploy=false with the versions pre-installed.
// 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
// spin up pods pointing to these revisions for each echo instance and skip tests accordingly.
// 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")
// If using this flag with --istio.test.revision, this flag will take precedence.
Revisions RevVerMap
// Image settings
Image ImageSettings
}
func (s Settings) Skip(class string) bool {
return s.SkipWorkloadClassesAsSet().Contains(class)
}
func (s *Settings) SkipWorkloadClassesAsSet() sets.Set {
return sets.New(s.SkipWorkloadClasses...)
}
// RunDir is the name of the dir to output, for this particular run.
func (s *Settings) RunDir() string {
u := strings.Replace(s.RunID.String(), "-", "", -1)
t := strings.Replace(s.TestID, "_", "-", -1)
// We want at least 6 characters of uuid padding
padding := maxTestIDLength - len(t)
if padding < 0 {
padding = 0
}
n := fmt.Sprintf("%s-%s", t, u[0:padding])
return path.Join(s.BaseDir, n)
}
// Clone settings
func (s *Settings) Clone() *Settings {
cl := *s
return &cl
}
// DefaultSettings returns a default settings instance.
func DefaultSettings() *Settings {
return &Settings{
RunID: uuid.New(),
}
}
// String implements fmt.Stringer
func (s *Settings) String() string {
result := ""
result += fmt.Sprintf("TestID: %s\n", s.TestID)
result += fmt.Sprintf("RunID: %s\n", s.RunID.String())
result += fmt.Sprintf("NoCleanup: %v\n", s.NoCleanup)
result += fmt.Sprintf("BaseDir: %s\n", s.BaseDir)
result += fmt.Sprintf("Selector: %v\n", s.Selector)
result += fmt.Sprintf("FailOnDeprecation: %v\n", s.FailOnDeprecation)
result += fmt.Sprintf("CIMode: %v\n", s.CIMode)
result += fmt.Sprintf("Retries: %v\n", s.Retries)
result += fmt.Sprintf("StableNamespaces: %v\n", s.StableNamespaces)
result += fmt.Sprintf("Revision: %v\n", s.Revision)
result += fmt.Sprintf("SkipWorkloads %v\n", s.SkipWorkloadClasses)
result += fmt.Sprintf("Compatibility: %v\n", s.Compatibility)
result += fmt.Sprintf("Revisions: %v\n", s.Revisions.String())
result += fmt.Sprintf("Hub: %s\n", s.Image.Hub)
result += fmt.Sprintf("Tag: %s\n", s.Image.Tag)
result += fmt.Sprintf("PullPolicy: %s\n", s.Image.PullPolicy)
result += fmt.Sprintf("PullSecret: %s\n", s.Image.PullSecret)
return result
}
type ArrayFlags []string
func (i *ArrayFlags) String() string {
return fmt.Sprint([]string(*i))
}
func (i *ArrayFlags) Set(value string) error {
*i = append(*i, value)
return nil
}