ExternalVizDeployReplicas has an external prometheus instance that's in a separate namespace
var ExternalVizDeployReplicas = map[string]DeploySpec{ "prometheus": {"external-prometheus", 1}, "metrics-api": {"linkerd-viz", 1}, "tap": {"linkerd-viz", 1}, "tap-injector": {"linkerd-viz", 1}, "web": {"linkerd-viz", 1}, }
LinkerdDeployReplicasEdge is a map containing the number of replicas for each Deployment and the main container name in the current core installation
var LinkerdDeployReplicasEdge = map[string]DeploySpec{ "linkerd-destination": {"linkerd", 1}, "linkerd-identity": {"linkerd", 1}, "linkerd-proxy-injector": {"linkerd", 1}, }
LinkerdDeployReplicasStable is a map containing the number of replicas for each Deployment and the main container name. Override whenever edge deviates from stable.
var LinkerdDeployReplicasStable = LinkerdDeployReplicasEdge
LinkerdVizDeployReplicas is a map containing the number of replicas for each Deployment and the main container name in the current linkerd-viz installation
var LinkerdVizDeployReplicas = map[string]DeploySpec{ "prometheus": {"linkerd-viz", 1}, "metrics-api": {"linkerd-viz", 1}, "tap": {"linkerd-viz", 1}, "tap-injector": {"linkerd-viz", 1}, "web": {"linkerd-viz", 1}, }
MulticlusterDeployReplicas is a map containing the number of replicas for each Deployment and the main container name for multicluster components
var MulticlusterDeployReplicas = map[string]DeploySpec{ "linkerd-gateway": {"linkerd-multicluster", 1}, }
MulticlusterSourceReplicas is a map containing the number of replicas for the Service Mirror component; component that we'd only expect in the source cluster.
var MulticlusterSourceReplicas = map[string]DeploySpec{ "linkerd-service-mirror-target": {Namespace: "linkerd-multicluster", Replicas: 1}, }
SourceContextKey represents the key used to get the name of the Kubernetes context corresponding to a source cluster in multicluster tests
var SourceContextKey = "source"
TargetContextKey represents the key used to get the name of the Kubernetes context corresponding to a source cluster in multicluster tests
var TargetContextKey = "target"
func AnnotatedError(t *testing.T, msg string, args ...interface{})
AnnotatedError is similar to Error() but it also admits a msg string that will be used as the GitHub annotation
func AnnotatedErrorf(t *testing.T, msg, format string, args ...interface{})
AnnotatedErrorf is similar to Errorf() but it also admits a msg string that will be used as the GitHub annotation
func AnnotatedFatal(t *testing.T, msg string, args ...interface{})
AnnotatedFatal is similar to Fatal() but it also admits a msg string that will be used as the GitHub annotation
func AnnotatedFatalf(t *testing.T, msg, format string, args ...interface{})
AnnotatedFatalf is similar to Fatalf() but it also admits a msg string that will be used as the GitHub annotation
func AnnotatedWarn(t *testing.T, msg string, args ...interface{})
AnnotatedWarn is a wrapper around t.Log() but it also admits a msg string that will be used as the GitHub warning annotation
func CheckRowCount(out string, expectedRowCount int) ([]string, error)
CheckRowCount checks that expectedRowCount rows have been returned
func Error(t *testing.T, args ...interface{})
Error is a wrapper around t.Error() args are passed to t.Error(args) and each arg will be sent to stdout formatted as a GitHub annotation when the envFlag environment variable is set
func Errorf(t *testing.T, format string, args ...interface{})
Errorf is a wrapper around t.Errorf() format and args are passed to t.Errorf(format, args) and the formatted message will be sent to stdout as a GitHub annotation when the envFlag environment variable is set
func ExerciseTestAppEndpoint(endpoint, namespace string, h *TestHelper) error
ExerciseTestAppEndpoint tests if the emojivoto service is reachable
func Fatal(t *testing.T, args ...interface{})
Fatal is a wrapper around t.Fatal() args are passed to t.Fatal(args) and each arg will be sent to stdout formatted as a GitHub annotation when the envFlag environment variable is set
func Fatalf(t *testing.T, format string, args ...interface{})
Fatalf is a wrapper around t.Errorf() format and args are passed to t.Fatalf(format, args) and the formatted message will be sent to stdout as a GitHub annotation when the envFlag environment variable is set
func GetProxyContainer(containers []v1.Container) *v1.Container
GetProxyContainer get the proxy containers
func ParseEvents(out string) ([]*corev1.Event, error)
ParseEvents parses the output of kubectl events
func ParseRows(out string, expectedRowCount, expectedColumnCount int) (map[string]*RowStat, error)
ParseRows parses the output of linkerd stat into a map of resource names to RowStat objects
func PatchDeploy(in string, name string, annotations map[string]string) (string, error)
PatchDeploy patches a manifest by applying annotations
func ReadFile(file string) (string, error)
ReadFile reads a file from disk and returns the contents as a string.
func ReadTestdata(fileName string) string
ReadTestdata reads a file and returns the contents of that file as a string.
func RetryFor(timeout time.Duration, fn func() error) error
RetryFor retries a given function every second until the function returns without an error, or a timeout is reached. If the timeout is reached, it returns the last error received from the function.
func TestResourcesPostInstall(namespace string, services []Service, deploys map[string]DeploySpec, h *TestHelper, t *testing.T)
TestResourcesPostInstall tests resources post control plane installation
func ValidateExpected(events []*TapEvent, expectedEvent TapEvent) error
ValidateExpected compares the received tap event with the expected tap event
DeploySpec is used to hold information about what deploys we should verify during testing
type DeploySpec struct { Namespace string Replicas int }
InjectValidator is used as a helper to generate correct injector flags and annotations and verify injected pods
type InjectValidator struct { NoInitContainer bool AutoInject bool AdminPort int ControlPort int EnableDebug bool EnableExternalProfiles bool ImagePullPolicy string InboundPort int InitImage string InitImageVersion string OutboundPort int CPULimit string EphemeralStorageLimit string CPURequest string MemoryLimit string MemoryRequest string EphemeralStorageRequest string Image string LogLevel string LogFormat string UID int GID int Version string RequireIdentityOnPorts string SkipOutboundPorts string OpaquePorts string SkipInboundPorts string OutboundConnectTimeout string InboundConnectTimeout string WaitBeforeExitSeconds int SkipSubnets string ShutdownGracePeriod string }
func (iv *InjectValidator) GetFlagsAndAnnotations() ([]string, map[string]string)
GetFlagsAndAnnotations retrieves the injector config flags and annotations based on the options provided
func (iv *InjectValidator) ValidatePod(pod *v1.PodSpec) error
ValidatePod validates that the pod had been configured according by the injector correctly
KubernetesHelper provides Kubernetes-related test helpers. It connects to the Kubernetes API using the environment's configured kubeconfig file.
type KubernetesHelper struct {
// contains filtered or unexported fields
}
func NewKubernetesHelper(k8sContext string, retryFor func(time.Duration, func() error) error) (*KubernetesHelper, error)
NewKubernetesHelper creates a new instance of KubernetesHelper.
func (h *KubernetesHelper) CheckIfNamespaceExists(ctx context.Context, namespace string) error
CheckIfNamespaceExists checks if a namespace exists.
func (h *KubernetesHelper) CheckPods(ctx context.Context, namespace string, deploymentName string, replicas int) error
CheckPods checks that a deployment in a namespace contains the expected number of pods in the Running state, and that no pods have been restarted.
func (h *KubernetesHelper) CheckService(ctx context.Context, namespace string, serviceName string) error
CheckService checks that a service exists in a namespace.
func (h *KubernetesHelper) CreateControlPlaneNamespaceIfNotExists(ctx context.Context, namespace string) error
CreateControlPlaneNamespaceIfNotExists creates linkerd control plane namespace.
func (h *KubernetesHelper) CreateDataPlaneNamespaceIfNotExists(ctx context.Context, namespace string, annotations map[string]string) error
CreateDataPlaneNamespaceIfNotExists creates a dataplane namespace if it does not already exist, with a test.linkerd.io/is-test-data-plane label for easier cleanup afterwards
func (h *KubernetesHelper) DeleteNamespaceIfExists(ctx context.Context, namespace string) error
DeleteNamespaceIfExists attempts to delete the given namespace, using the K8s API directly
func (h *KubernetesHelper) GetConfigUID(ctx context.Context, namespace string) (string, error)
GetConfigUID returns the uid associated to the linkerd-config ConfigMap resource in the given namespace
func (h *KubernetesHelper) GetEndpoints(ctx context.Context, namespace string, serviceName string) (*corev1.Endpoints, error)
GetEndpoints gets endpoints that exist in a namespace.
func (h *KubernetesHelper) GetPodNamesForDeployment(ctx context.Context, namespace string, deploymentName string) ([]string, error)
GetPodNamesForDeployment returns all pod names for the given deployment
func (h *KubernetesHelper) GetPods(ctx context.Context, namespace string, podLabels map[string]string) ([]corev1.Pod, error)
GetPods returns all pods with the given labels
func (h *KubernetesHelper) GetPodsForDeployment(ctx context.Context, namespace string, deploymentName string) ([]corev1.Pod, error)
GetPodsForDeployment returns all pods for the given deployment
func (h *KubernetesHelper) GetResources(ctx context.Context, containerName, deploymentName, namespace string) (corev1.ResourceRequirements, error)
GetResources returns the resource limits and requests set on a deployment of the set name in the given namespace
func (h *KubernetesHelper) GetSecret(ctx context.Context, namespace, name string) (*corev1.Secret, error)
GetSecret retrieves a Kubernetes Secret
func (h *KubernetesHelper) GetService(ctx context.Context, namespace string, serviceName string) (*corev1.Service, error)
GetService gets a service that exists in a namespace.
func (h *KubernetesHelper) Kubectl(stdin string, arg ...string) (string, error)
Kubectl executes an arbitrary Kubectl command
func (h *KubernetesHelper) KubectlApply(stdin string, namespace string) (string, error)
KubectlApply applies a given configuration string in a namespace. If the namespace does not exist, it creates it first. If no namespace is provided, it does not specify the `--namespace` flag.
func (h *KubernetesHelper) KubectlApplyWithArgs(stdin string, cmdArgs ...string) (string, error)
KubectlApplyWithArgs applies a given configuration string with the passed flags
func (h *KubernetesHelper) KubectlApplyWithContext(stdin string, context string, arg ...string) (string, error)
KubectlApplyWithContext applies a given configuration with the given flags
func (h *KubernetesHelper) KubectlWithContext(stdin string, context string, arg ...string) (string, error)
KubectlWithContext will call the kubectl binary with any optional arguments provided and an arbitrary, given context. Useful when working with k8s resources in a multi-cluster context. Optionally, stdin can be piped to kubectl.
func (h *KubernetesHelper) ParseNamespacedResource(resource string) (string, string, error)
ParseNamespacedResource extracts a namespace and resource name from a string that's in the format namespace/resource. If the strings is in a different format it returns an error.
func (h *KubernetesHelper) SwitchContext(ctx string) error
SwitchContext will re-build the clientset with the given context. Useful when testing multiple clusters at the same time
func (h *KubernetesHelper) URLFor(ctx context.Context, namespace, deployName string, remotePort int) (string, error)
URLFor creates a kubernetes port-forward, runs it, and returns the URL that tests can use for access to the given deployment. Note that the port-forward remains running for the duration of the test.
func (h *KubernetesHelper) WaitRollout(t *testing.T, deploys map[string]DeploySpec)
WaitRollout blocks until all the given deployments have been completely rolled out (and their pods are ready)
func (h *KubernetesHelper) WaitRolloutWithContext(t *testing.T, deploys map[string]DeploySpec, context string)
WaitRolloutWithContext blocks until all the given deployments in a provided k8s context have been completely rolled out (and their pods are ready)
func (h *KubernetesHelper) WaitUntilDeployReady(deploys map[string]DeploySpec)
WaitUntilDeployReady will block and wait until all given deploys have been rolled out and their pods are in a 'ready' status. The difference between this and WaitRollout is that WaitUntilDeployReady uses CheckPods underneath, instead of relying on the 'rollout' command. WaitUntilDeployReady will also retry for a long period time. This function is used to block tests from running until the control plane and extensions are ready.
RestartCountError is returned by CheckPods() whenever a pod has restarted exactly one time. Consumers should log this type of error instead of failing the test. This is to alleviate CI flakiness stemming from a containerd bug. See https://github.com/kubernetes/kubernetes/issues/89064 See https://github.com/containerd/containerd/issues/4068
type RestartCountError struct {
// contains filtered or unexported fields
}
func (e *RestartCountError) Error() string
RowStat is used to store the contents for a single row from the stat command
type RowStat struct { Name string Status string Meshed string Success string Rps string P50Latency string P95Latency string P99Latency string TCPOpenConnections string UnauthorizedRPS string }
Service is used to hold information about a Service we should verify during testing
type Service struct { Namespace string Name string }
Stream provides the ability of read the output of an executing process while it is still running
type Stream struct {
// contains filtered or unexported fields
}
func (s *Stream) ReadUntil(lineCount int, timeout time.Duration) ([]string, error)
ReadUntil reads from the process output until specified number of lines has been reached, or until a timeout
func (s *Stream) Stop()
Stop closes the stream and kills the process
TapEvent represents a tap event
type TapEvent struct { Method string Authority string Path string HTTPStatus string GrpcStatus string TLS string LineCount int }
func Tap(target string, h *TestHelper, arg ...string) ([]*TapEvent, error)
Tap executes a tap command and converts the command's streaming output into tap events using each line's "id" field
TestDataDiffer holds configuration for generating test diff
type TestDataDiffer struct { PrettyDiff bool UpdateFixtures bool RejectPath string }
func (td *TestDataDiffer) DiffTestYAML(path string, actualYAML string) error
DiffTestYAML compares a YAML structure to a fixture on the filestystem.
func (td *TestDataDiffer) DiffTestYAMLTemplate(path string, actualYAML string, params any) error
DiffTestYAMLTemplate compares a YAML structure to a parameterized fixture on the filestystem.
func (td *TestDataDiffer) DiffTestdata(t *testing.T, path, actual string)
DiffTestdata generates the diff for actual w.r.the file in path
TestHelper provides helpers for running the linkerd integration tests.
type TestHelper struct { KubernetesHelper // contains filtered or unexported fields }
func NewGenericTestHelper( linkerd, version, namespace, vizNamespace, upgradeFromVersion, clusterDomain, helmPath, helmCharts, helmReleaseName, helmMulticlusterReleaseName, helmMulticlusterChart string, externalIssuer, externalPrometheus, multicluster, cni, calico, uninstall bool, httpClient http.Client, kubernetesHelper KubernetesHelper, ) *TestHelper
NewGenericTestHelper returns a new *TestHelper from the options provided as function parameters. This helper was created to be able to reuse this package without hard restrictions as seen in `NewTestHelper()` which is primarily used with integration tests See - https://github.com/linkerd/linkerd2/issues/4530
func NewTestHelper() *TestHelper
NewTestHelper creates a new instance of TestHelper for the current test run. The new TestHelper can be configured via command line flags.
func (h *TestHelper) AddInstalledExtension(extensionName string)
AddInstalledExtension adds an extension name to installedExtensions to track the currently installed linkerd extensions.
func (h *TestHelper) CNI() bool
CNI determines whether CNI should be enabled
func (h *TestHelper) Calico() bool
Calico determines whether Calico CNI plug-in is enabled
func (h *TestHelper) CheckVersion(serverVersion string) error
CheckVersion validates the output of the "linkerd version" command.
func (h *TestHelper) CmdRun(cmd string, arg ...string) (string, error)
CmdRun executes an arbitrary command by calling the binary and return its output
func (h *TestHelper) CreateTLSSecret(name, root, cert, key string) error
CreateTLSSecret creates a TLS Kubernetes secret
func (h *TestHelper) DefaultInboundPolicy() string
DefaultInboundPolicy returns the override value for proxy.defaultInboundPolicy
func (h *TestHelper) DownloadCLIBinary(filepath, version string) error
DownloadCLIBinary is used to download the Linkerd CLI from GitHub Releases page. The method takes the version to download and a filepath where to save the binary.
func (h *TestHelper) DualStack() bool
DualStack determines whether the DualStack tests are run
func (h *TestHelper) ExternalIssuer() bool
ExternalIssuer determines whether linkerd should be installed with --identity-external-issuer
func (h *TestHelper) ExternalPrometheus() bool
ExternalPrometheus determines whether linkerd should be installed with --set prometheusUrl
func (h *TestHelper) GetClusterDomain() string
GetClusterDomain returns the custom cluster domain that needs to be used during linkerd installation
func (h *TestHelper) GetHelmCharts() string
GetHelmCharts returns the path to the Linkerd Helm chart
func (h *TestHelper) GetHelmReleaseName() string
GetHelmReleaseName returns the name of the Linkerd installation Helm release
func (h *TestHelper) GetInstalledExtensions() []string
GetInstalledExtensions gets a list currently installed extensions in a test run.
func (h *TestHelper) GetLinkerdNamespace() string
GetLinkerdNamespace returns the namespace where linkerd is installed. Set the namespace using the -linkerd-namespace command line flag.
func (h *TestHelper) GetLinkerdVizHelmChart() string
GetLinkerdVizHelmChart returns the path to the Linkerd viz Helm chart
func (h *TestHelper) GetLinkerdVizHelmStableChart() string
GetLinkerdVizHelmStableChart returns the path to the Linkerd viz Helm stable chart
func (h *TestHelper) GetMulticlusterContexts() map[string]string
GetMulticlusterContexts returns a map with the context names for the clusters used in the test
func (h *TestHelper) GetMulticlusterHelmChart() string
GetMulticlusterHelmChart returns the path to the Linkerd multicluster Helm chart
func (h *TestHelper) GetMulticlusterHelmReleaseName() string
GetMulticlusterHelmReleaseName returns the name of the Linkerd multicluster installation Helm release
func (h *TestHelper) GetMulticlusterNamespace() string
GetMulticlusterNamespace returns the namespace where multicluster components are installed.
func (h *TestHelper) GetReleaseChannelVersions() (map[string]string, error)
GetReleaseChannelVersions is used to fetch the latest versions for Linkerd's release channels: edge and stable
func (h *TestHelper) GetTestNamespace(testName string) string
GetTestNamespace returns the namespace for the given test. The test namespace is prefixed with the linkerd namespace.
func (h *TestHelper) GetVersion() string
GetVersion returns the version of linkerd to test. This version corresponds to the client version of the linkerd binary provided via the -linkerd command line flag.
func (h *TestHelper) GetVizNamespace() string
GetVizNamespace returns the namespace where linkerd Viz Extension is installed. Set the namespace using the -linkerd-namespace command line flag.
func (h *TestHelper) HTTPGetURL(url string) (string, error)
HTTPGetURL sends a GET request to the given URL. It returns the response body in the event of a successful 200 response. In the event of a non-200 response, it returns an error. It retries requests for up to 30 seconds, giving pods time to start.
func (h *TestHelper) HelmCmdPlain(cmd, chart, releaseName string, arg ...string) (string, string, error)
HelmCmdPlain runs a helm subcommand, with the provided arguments and no defaults
func (h *TestHelper) HelmInstall(chart, releaseName string, arg ...string) (string, string, error)
HelmInstall runs the helm install subcommand, with the provided arguments
func (h *TestHelper) HelmInstallMulticluster(chart string, arg ...string) (string, string, error)
HelmInstallMulticluster runs the helm install subcommand for multicluster, with the provided arguments
func (h *TestHelper) HelmRun(arg ...string) (string, string, error)
HelmRun executes a helm command appended with the --context
func (h *TestHelper) HelmUninstallMulticluster(chart string) (string, string, error)
HelmUninstallMulticluster runs the helm delete subcommand for multicluster
func (h *TestHelper) HelmUpgrade(chart, releaseName string, arg ...string) (string, string, error)
HelmUpgrade runs the helm upgrade subcommand, with the provided arguments
func (h *TestHelper) KubectlStream(arg ...string) (*Stream, error)
KubectlStream initiates a kubectl command appended with the --namespace flag, and returns a Stream that can be used to read the command's output while it is still executing.
func (h *TestHelper) LinkerdRun(arg ...string) (string, error)
LinkerdRun executes a linkerd command returning its stdout.
func (h *TestHelper) LinkerdRunStream(arg ...string) (*Stream, error)
LinkerdRunStream initiates a linkerd command appended with the --linkerd-namespace flag, and returns a Stream that can be used to read the command's output while it is still executing.
func (h *TestHelper) Multicluster() bool
Multicluster determines whether multicluster components should be installed
func (h *TestHelper) NativeSidecar() bool
NativeSidecar determines whether native sidecar injection is enabled
func (h *TestHelper) PipeToHelmRun(stdin string, arg ...string) (string, string, error)
PipeToHelmRun executes a Helm command appended with the --context flag, and provides a string at Stdin.
func (h *TestHelper) PipeToLinkerdRun(stdin string, arg ...string) (string, string, error)
PipeToLinkerdRun executes a linkerd command appended with the --linkerd-namespace flag, and provides a string at Stdin.
func (h *TestHelper) TestCheck(extraArgs ...string) error
TestCheck runs validates the output of `linkerd check`
func (h *TestHelper) TestCheckPre() error
TestCheckPre runs validates the output of `linkerd check --pre`
func (h *TestHelper) TestCheckProxy(expectedVersion, namespace string) error
TestCheckProxy runs validates the output of `linkerd check --proxy`
func (h *TestHelper) TestCheckWith(additional []healthcheck.CategoryID, extraArgs ...string) error
TestCheckWith validates the output of `linkerd check`. It will validate the core categories and any additional categories that the caller provides.
func (h *TestHelper) Uninstall() bool
Uninstall determines whether the "linkerd uninstall" integration test should be run
func (h *TestHelper) UpgradeFromVersion() string
UpgradeFromVersion returns the base version of the upgrade test.
func (h *TestHelper) UpgradeHelmFromVersion() string
UpgradeHelmFromVersion returns the version from which Linkerd should be upgraded with Helm
func (h *TestHelper) ValidateOutput(out, fixtureFile string) error
ValidateOutput validates a string against the contents of a file in the test's testdata directory.
func (h *TestHelper) WithDataPlaneNamespace(ctx context.Context, testName string, annotations map[string]string, t *testing.T, test func(t *testing.T, ns string))
WithDataPlaneNamespace is used to create a test namespace that is deleted before the function returns