knative.dev/pkg@v0.0.0-20260602142205-ac97e43f6622/test/request.go (about)

     1  /*
     2  Copyright 2018 The Knative 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  // request contains logic to make polling HTTP requests against an endpoint with optional host spoofing.
    18  
    19  package test
    20  
    21  import (
    22  	"context"
    23  	"net/url"
    24  	"time"
    25  
    26  	"k8s.io/client-go/kubernetes"
    27  	"knative.dev/pkg/test/logging"
    28  	"knative.dev/pkg/test/spoof"
    29  )
    30  
    31  // RequestOption enables configuration of requests
    32  // when polling for endpoint states.
    33  type RequestOption = spoof.RequestOption
    34  
    35  // WithHeader will add the provided headers to the request.
    36  //
    37  // Deprecated: Use the spoof package version
    38  var WithHeader = spoof.WithHeader
    39  
    40  // IsOneOfStatusCodes checks that the response code is equal to the given one.
    41  //
    42  // Deprecated: Use the spoof package version
    43  var IsOneOfStatusCodes = spoof.IsOneOfStatusCodes
    44  
    45  // IsStatusOK checks that the response code is a 200.
    46  //
    47  // Deprecated: Use the spoof package version
    48  var IsStatusOK = spoof.IsStatusOK
    49  
    50  // MatchesAllBodies checks that the *first* response body matches the "expected" body, otherwise failing.
    51  //
    52  // Deprecated: Use the spoof package version
    53  var MatchesAllBodies = spoof.MatchesAllBodies
    54  
    55  // MatchesBody checks that the *first* response body matches the "expected" body, otherwise failing.
    56  //
    57  // Deprecated: Use the spoof package version
    58  var MatchesBody = spoof.MatchesBody
    59  
    60  // MatchesAllOf combines multiple ResponseCheckers to one ResponseChecker with a logical AND. The
    61  // checkers are executed in order. The first function to trigger an error or a retry will short-circuit
    62  // the other functions (they will not be executed).
    63  //
    64  // This is useful for combining a body with a status check like:
    65  // MatchesAllOf(IsStatusOK, MatchesBody("test"))
    66  //
    67  // The MatchesBody check will only be executed after the IsStatusOK has passed.
    68  //
    69  // Deprecated: Use the spoof package version
    70  var MatchesAllOf = spoof.MatchesAllOf
    71  
    72  // WaitForEndpointState will poll an endpoint until inState indicates the state is achieved,
    73  // or default timeout is reached.
    74  // If resolvableDomain is false, it will use kubeClientset to look up the ingress and spoof
    75  // the domain in the request headers, otherwise it will make the request directly to domain.
    76  // desc will be used to name the metric that is emitted to track how long it took for the
    77  // domain to get into the state checked by inState.  Commas in `desc` must be escaped.
    78  func WaitForEndpointState(
    79  	ctx context.Context,
    80  	kubeClient kubernetes.Interface,
    81  	logf logging.FormatLogger,
    82  	url *url.URL,
    83  	inState spoof.ResponseChecker,
    84  	desc string,
    85  	resolvable bool,
    86  	opts ...interface{},
    87  ) (*spoof.Response, error) {
    88  	return WaitForEndpointStateWithTimeout(ctx, kubeClient, logf, url, inState,
    89  		desc, resolvable, Flags.SpoofRequestTimeout, opts...)
    90  }
    91  
    92  // WaitForEndpointStateWithTimeout will poll an endpoint until inState indicates the state is achieved
    93  // or the provided timeout is achieved.
    94  // If resolvableDomain is false, it will use kubeClientset to look up the ingress and spoof
    95  // the domain in the request headers, otherwise it will make the request directly to domain.
    96  // desc will be used to name the metric that is emitted to track how long it took for the
    97  // domain to get into the state checked by inState.  Commas in `desc` must be escaped.
    98  func WaitForEndpointStateWithTimeout(
    99  	ctx context.Context,
   100  	kubeClient kubernetes.Interface,
   101  	logf logging.FormatLogger,
   102  	url *url.URL,
   103  	inState spoof.ResponseChecker,
   104  	desc string,
   105  	resolvable bool,
   106  	timeout time.Duration,
   107  	opts ...interface{},
   108  ) (*spoof.Response, error) {
   109  	client, rOpts, err := makeSpoofClient(ctx, kubeClient, logf, url, resolvable, timeout, opts...)
   110  	if err != nil {
   111  		return nil, err
   112  	}
   113  	return client.WaitForEndpointState(ctx, url, inState, desc, rOpts...)
   114  }
   115  
   116  func makeSpoofClient(
   117  	ctx context.Context,
   118  	kubeClient kubernetes.Interface,
   119  	logf logging.FormatLogger,
   120  	url *url.URL,
   121  	resolvable bool,
   122  	timeout time.Duration,
   123  	opts ...interface{},
   124  ) (*spoof.SpoofingClient, []spoof.RequestOption, error) {
   125  	var tOpts []spoof.TransportOption
   126  	var rOpts []spoof.RequestOption
   127  
   128  	for _, opt := range opts {
   129  		switch o := opt.(type) {
   130  		case spoof.RequestOption:
   131  			rOpts = append(rOpts, o)
   132  		case spoof.TransportOption:
   133  			tOpts = append(tOpts, o)
   134  		}
   135  	}
   136  
   137  	client, err := NewSpoofingClient(ctx, kubeClient, logf, url.Hostname(), resolvable, tOpts...)
   138  	if err != nil {
   139  		return nil, nil, err
   140  	}
   141  	client.RequestTimeout = timeout
   142  
   143  	return client, rOpts, nil
   144  }
   145  
   146  func CheckEndpointState(
   147  	ctx context.Context,
   148  	kubeClient kubernetes.Interface,
   149  	logf logging.FormatLogger,
   150  	url *url.URL,
   151  	inState spoof.ResponseChecker,
   152  	desc string,
   153  	resolvable bool,
   154  	opts ...interface{},
   155  ) (*spoof.Response, error) {
   156  	client, rOpts, err := makeSpoofClient(ctx, kubeClient, logf, url, resolvable, Flags.SpoofRequestTimeout, opts...)
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	return client.CheckEndpointState(ctx, url, inState, desc, rOpts...)
   161  }