Files
higress/test/ingress/conformance/utils/kubernetes/helpers.go
2023-01-18 17:36:10 +08:00

123 lines
4.1 KiB
Go

// Copyright (c) 2022 Alibaba Group Holding Ltd.
//
// 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 kubernetes
import (
"context"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"sigs.k8s.io/controller-runtime/pkg/client"
"github.com/alibaba/higress/test/ingress/conformance/utils/config"
)
// FilterStaleConditions returns the list of status condition whos observedGeneration does not
// match the objects metadata.Generation
func FilterStaleConditions(obj metav1.Object, conditions []metav1.Condition) []metav1.Condition {
stale := make([]metav1.Condition, 0, len(conditions))
for _, condition := range conditions {
if obj.GetGeneration() != condition.ObservedGeneration {
stale = append(stale, condition)
}
}
return stale
}
// NamespacesMustBeAccepted waits until all Pods are marked ready
// in the provided namespaces. This will cause the test to
// halt if the specified timeout is exceeded.
func NamespacesMustBeAccepted(t *testing.T, c client.Client, timeoutConfig config.TimeoutConfig, namespaces []string) {
t.Helper()
waitErr := wait.PollImmediate(1*time.Second, timeoutConfig.NamespacesMustBeReady, func() (bool, error) {
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
for _, ns := range namespaces {
podList := &v1.PodList{}
err := c.List(ctx, podList, client.InNamespace(ns))
if err != nil {
t.Errorf("Error listing Pods: %v", err)
}
for _, pod := range podList.Items {
if !FindPodConditionInList(t, pod.Status.Conditions, "Ready", "True") &&
pod.Status.Phase != v1.PodSucceeded {
t.Logf("%s/%s Pod not ready yet", ns, pod.Name)
return false, nil
}
}
}
t.Logf("Gateways and Pods in %s namespaces ready", strings.Join(namespaces, ", "))
return true, nil
})
require.NoErrorf(t, waitErr, "error waiting for %s namespaces to be ready", strings.Join(namespaces, ", "))
}
func ConditionsMatch(t *testing.T, expected, actual []metav1.Condition) bool {
if len(actual) < len(expected) {
t.Logf("Expected more conditions to be present")
return false
}
for _, condition := range expected {
if !FindConditionInList(t, actual, condition.Type, string(condition.Status), condition.Reason) {
return false
}
}
t.Logf("Conditions matched expectations")
return true
}
// findConditionInList finds a condition in a list of Conditions, checking
// the Name, Value, and Reason. If an empty reason is passed, any Reason will match.
func FindConditionInList(t *testing.T, conditions []metav1.Condition, condName, expectedStatus, expectedReason string) bool {
for _, cond := range conditions {
if cond.Type == condName {
if cond.Status == metav1.ConditionStatus(expectedStatus) {
// an empty Reason string means "Match any reason".
if expectedReason == "" || cond.Reason == expectedReason {
return true
}
t.Logf("%s condition Reason set to %s, expected %s", condName, cond.Reason, expectedReason)
}
t.Logf("%s condition set to Status %s with Reason %v, expected Status %s", condName, cond.Status, cond.Reason, expectedStatus)
}
}
t.Logf("%s was not in conditions list", condName)
return false
}
func FindPodConditionInList(t *testing.T, conditions []v1.PodCondition, condName, condValue string) bool {
for _, cond := range conditions {
if cond.Type == v1.PodConditionType(condName) {
if cond.Status == v1.ConditionStatus(condValue) {
return true
}
t.Logf("%s condition set to %s, expected %s", condName, cond.Status, condValue)
}
}
t.Logf("%s was not in conditions list", condName)
return false
}