...

Source file src/k8s.io/kubernetes/test/utils/ktesting/contexthelper_test.go

Documentation: k8s.io/kubernetes/test/utils/ktesting

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package ktesting
    18  
    19  import (
    20  	"context"
    21  	"errors"
    22  	"os"
    23  	"strings"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/stretchr/testify/assert"
    28  )
    29  
    30  func TestCleanupErr(t *testing.T) {
    31  	actual := cleanupErr(t.Name())
    32  	if !errors.Is(actual, context.Canceled) {
    33  		t.Errorf("cleanupErr %T should be a %T", actual, context.Canceled)
    34  	}
    35  }
    36  
    37  func TestCause(t *testing.T) {
    38  	timeoutCause := canceledError("I timed out")
    39  	parentCause := errors.New("parent canceled")
    40  
    41  	t.Parallel()
    42  	for name, tt := range map[string]struct {
    43  		parentCtx              context.Context
    44  		timeout                time.Duration
    45  		sleep                  time.Duration
    46  		cancelCause            string
    47  		expectErr, expectCause error
    48  		expectDeadline         time.Duration
    49  	}{
    50  		"nothing": {
    51  			parentCtx: context.Background(),
    52  			timeout:   5 * time.Millisecond,
    53  			sleep:     time.Millisecond,
    54  		},
    55  		"timeout": {
    56  			parentCtx:   context.Background(),
    57  			timeout:     time.Millisecond,
    58  			sleep:       5 * time.Millisecond,
    59  			expectErr:   context.Canceled,
    60  			expectCause: canceledError(timeoutCause),
    61  		},
    62  		"parent-canceled": {
    63  			parentCtx: func() context.Context {
    64  				ctx, cancel := context.WithCancel(context.Background())
    65  				cancel()
    66  				return ctx
    67  			}(),
    68  			timeout:     time.Millisecond,
    69  			sleep:       5 * time.Millisecond,
    70  			expectErr:   context.Canceled,
    71  			expectCause: context.Canceled,
    72  		},
    73  		"parent-cause": {
    74  			parentCtx: func() context.Context {
    75  				ctx, cancel := context.WithCancelCause(context.Background())
    76  				cancel(parentCause)
    77  				return ctx
    78  			}(),
    79  			timeout:     time.Millisecond,
    80  			sleep:       5 * time.Millisecond,
    81  			expectErr:   context.Canceled,
    82  			expectCause: parentCause,
    83  		},
    84  		"deadline-no-parent": {
    85  			parentCtx:      context.Background(),
    86  			timeout:        time.Minute,
    87  			expectDeadline: time.Minute,
    88  		},
    89  		"deadline-parent": {
    90  			parentCtx: func() context.Context {
    91  				ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
    92  				t.Cleanup(cancel)
    93  				return ctx
    94  			}(),
    95  			timeout:        2 * time.Minute,
    96  			expectDeadline: time.Minute,
    97  		},
    98  		"deadline-child": {
    99  			parentCtx: func() context.Context {
   100  				ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
   101  				t.Cleanup(cancel)
   102  				return ctx
   103  			}(),
   104  			timeout:        time.Minute,
   105  			expectDeadline: time.Minute,
   106  		},
   107  	} {
   108  		tt := tt
   109  		t.Run(name, func(t *testing.T) {
   110  			ctx, cancel := withTimeout(tt.parentCtx, t, tt.timeout, timeoutCause.Error())
   111  			if tt.cancelCause != "" {
   112  				cancel(tt.cancelCause)
   113  			}
   114  			if tt.expectDeadline != 0 {
   115  				actualDeadline, ok := ctx.Deadline()
   116  				if assert.True(t, ok, "should have had a deadline") {
   117  					// Testing timing behavior is unreliable in Prow because
   118  					// the test runs in parallel with several others.
   119  					// Therefore this check is skipped if a CI environment is
   120  					// detected.
   121  					ci, _ := os.LookupEnv("CI")
   122  					switch strings.ToLower(ci) {
   123  					case "yes", "true", "1":
   124  						// Skip.
   125  					default:
   126  						assert.InDelta(t, time.Until(actualDeadline), tt.expectDeadline, float64(time.Second), "remaining time till Deadline()")
   127  					}
   128  				}
   129  			}
   130  			time.Sleep(tt.sleep)
   131  			actualErr := ctx.Err()
   132  			actualCause := context.Cause(ctx)
   133  			ci, _ := os.LookupEnv("CI")
   134  			switch strings.ToLower(ci) {
   135  			case "yes", "true", "1":
   136  				// Skip.
   137  			default:
   138  				assert.Equal(t, tt.expectErr, actualErr, "ctx.Err()")
   139  				assert.Equal(t, tt.expectCause, actualCause, "context.Cause()")
   140  			}
   141  		})
   142  	}
   143  }
   144  

View as plain text