Skip to content

Commit

Permalink
[WIP] refacto and add some comments to clarify
Browse files Browse the repository at this point in the history
  • Loading branch information
norbjd committed Apr 7, 2024
1 parent 77b783e commit f319b6c
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 19 deletions.
3 changes: 2 additions & 1 deletion test/e2e-kind.sh
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,8 @@ export "GATEWAY_NAMESPACE_OVERRIDE=${KOURIER_GATEWAY_NAMESPACE}"
#

echo ">> Change DRAIN_TIME_SECONDS for graceful shutdown tests"
kubectl -n "${KOURIER_GATEWAY_NAMESPACE}" set env deployment 3scale-kourier-gateway DRAIN_TIME_SECONDS="25"
export DRAIN_TIME_SECONDS=25
kubectl -n "${KOURIER_GATEWAY_NAMESPACE}" set env deployment 3scale-kourier-gateway DRAIN_TIME_SECONDS="$DRAIN_TIME_SECONDS"
kubectl -n "${KOURIER_GATEWAY_NAMESPACE}" rollout status deployment/3scale-kourier-gateway --timeout=300s

echo ">> Running graceful shutdown tests"
Expand Down
62 changes: 44 additions & 18 deletions test/gracefulshutdown/gracefulshutdown_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,18 +35,37 @@ import (
"knative.dev/networking/test/conformance/ingress"
)

const kourierGatewayLabel = "app=3scale-kourier-gateway"
const (
kourierGatewayNamespace = "kourier-system"
kourierGatewayLabel = "app=3scale-kourier-gateway"
)

func TestGracefulShutdown(t *testing.T) {
kourierGatewayNamespace := os.Getenv("GATEWAY_NAMESPACE_OVERRIDE")
if kourierGatewayNamespace == "" {
t.Fatal("GATEWAY_NAMESPACE_OVERRIDE env var must be set")
gatewayNs := kourierGatewayNamespace
if gatewayNsOverride := os.Getenv("GATEWAY_NAMESPACE_OVERRIDE"); gatewayNsOverride != "" {
gatewayNs = gatewayNsOverride
}

// Retrieve drain time from environment
var drainTime time.Duration
drainTimeSeconds := os.Getenv("DRAIN_TIME_SECONDS")
if drainTimeSeconds == "" {
t.Fatal("DRAIN_TIME_SECONDS environment variable must be set")
}

drainTime, err := time.ParseDuration(fmt.Sprintf("%ds", drainTimeSeconds))

Check failure on line 56 in test/gracefulshutdown/gracefulshutdown_test.go

View workflow job for this annotation

GitHub Actions / style / Golang / Lint

printf: fmt.Sprintf format %d has arg drainTimeSeconds of wrong type string (govet)
if err != nil {
t.Fatal("DRAIN_TIME_SECONDS is an invalid duration:", err)
}
if drainTime <= 5*time.Second {
t.Fatal("DRAIN_TIME_SECONDS must be greater than 5")
}

clients := test.Setup(t)
ctx := context.Background()

gatewayPods, err := clients.KubeClient.CoreV1().Pods(kourierGatewayNamespace).List(ctx, metav1.ListOptions{
// Retrieve the gateway pod name
gatewayPods, err := clients.KubeClient.CoreV1().Pods(gatewayNs).List(ctx, metav1.ListOptions{
LabelSelector: kourierGatewayLabel,
})
if err != nil {
Expand All @@ -58,6 +77,7 @@ func TestGracefulShutdown(t *testing.T) {

gatewayPodName := gatewayPods.Items[0].Name

// Create a service and an ingress
name, port, _ := ingress.CreateTimeoutService(ctx, t, clients)
_, client, _ := ingress.CreateIngressReady(ctx, t, clients, v1alpha1.IngressSpec{
Rules: []v1alpha1.IngressRule{{
Expand All @@ -77,39 +97,45 @@ func TestGracefulShutdown(t *testing.T) {
}},
})

delay := 20 * time.Second

var statusCode int

reqURL := fmt.Sprintf("http://%s.example.com?initialTimeout=%d", name, delay.Milliseconds())
// Prepare the request to the ingress: this request will wait for slightly less than the drain time configured
requestTimeout := drainTime - (3 * time.Second)
reqURL := fmt.Sprintf("http://%s.example.com?initialTimeout=%d", name, requestTimeout.Milliseconds())
req, err := http.NewRequest("GET", reqURL, nil)
if err != nil {
t.Fatal("Error making GET request:", err)
}

errs := make(chan error, 1)
var statusCode int

// Do the request asynchronously: goroutine will return only once the service has returned a response (after initialTimeout),
// or early if there is an error
go func() {
resp, err := client.Do(req)
defer resp.Body.Close()

if err == nil {
statusCode = resp.StatusCode
if err != nil {
errs <- err
return
}

errs <- err
}()
statusCode = resp.StatusCode
resp.Body.Close()

time.Sleep(2 * time.Second)
errs <- nil
}()

if err := clients.KubeClient.CoreV1().Pods(kourierGatewayNamespace).Delete(ctx, gatewayPodName, metav1.DeleteOptions{}); err != nil {
// In parallel, delete the gateway pod:
// the 1 second sleep before the deletion is here to ensure the request has been sent by the goroutine above
time.Sleep(1 * time.Second)
if err := clients.KubeClient.CoreV1().Pods(gatewayNs).Delete(ctx, gatewayPodName, metav1.DeleteOptions{}); err != nil {
t.Fatalf("Failed to delete pod %s: %v", gatewayPodName, err)
}

// Wait until we get a response from the asynchronous request
err = <-errs
if err != nil {
t.Fatal(err)
}

// The gateway has been gracefully shutdown, so the in-flight request finishes with a OK status code
assert.Equal(t, statusCode, http.StatusOK)
}

0 comments on commit f319b6c

Please sign in to comment.