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

     1  /*
     2  Copyright 2019 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  // spoof contains logic to make polling HTTP requests against an endpoint with optional host spoofing.
    18  
    19  package spoof
    20  
    21  import (
    22  	"errors"
    23  	"net/http"
    24  	"testing"
    25  )
    26  
    27  func TestDNSError(t *testing.T) {
    28  	client := &http.Client{}
    29  
    30  	for _, tt := range []struct {
    31  		name     string
    32  		url      string
    33  		dnsError bool
    34  	}{{
    35  		name:     "url does not exist",
    36  		url:      "http://this.url.does.not.exist",
    37  		dnsError: true,
    38  	}, {
    39  		name:     "ip address",
    40  		url:      "http://127.0.0.1",
    41  		dnsError: false,
    42  	}, {
    43  		name:     "localhost",
    44  		url:      "http://localhost:8080",
    45  		dnsError: false,
    46  	}, {
    47  		name:     "no error",
    48  		url:      "http://google.com",
    49  		dnsError: false,
    50  	}} {
    51  		t.Run(tt.name, func(t *testing.T) {
    52  			req, _ := http.NewRequest(http.MethodGet, tt.url, nil)
    53  			resp, err := client.Do(req)
    54  			if resp != nil {
    55  				defer resp.Body.Close()
    56  			}
    57  			if dnsError := isDNSError(err); tt.dnsError != dnsError {
    58  				t.Errorf("Expected dnsError=%v, got %v", tt.dnsError, dnsError)
    59  			}
    60  		})
    61  	}
    62  }
    63  
    64  func TestConnectionRefused(t *testing.T) {
    65  	client := &http.Client{}
    66  
    67  	for _, tt := range []struct {
    68  		name        string
    69  		url         string
    70  		connRefused bool
    71  	}{{
    72  		name:        "nothing listening",
    73  		url:         "http://localhost:60001",
    74  		connRefused: true,
    75  	}, {
    76  		name:        "dns error",
    77  		url:         "http://this.url.does.not.exist",
    78  		connRefused: false,
    79  	}, {
    80  		name:        "google.com",
    81  		url:         "https://google.com",
    82  		connRefused: false,
    83  	}} {
    84  		t.Run(tt.name, func(t *testing.T) {
    85  			req, _ := http.NewRequest(http.MethodGet, tt.url, nil)
    86  			resp, err := client.Do(req)
    87  			if resp != nil {
    88  				defer resp.Body.Close()
    89  			}
    90  			if connRefused := isConnectionRefused(err); tt.connRefused != connRefused {
    91  				t.Errorf("Expected connRefused=%v, got %v", tt.connRefused, connRefused)
    92  			}
    93  		})
    94  	}
    95  }
    96  
    97  func TestConnectionReset(t *testing.T) {
    98  	for _, tt := range []struct {
    99  		name      string
   100  		err       error
   101  		connReset bool
   102  	}{{
   103  		name:      "error matching",
   104  		err:       errors.New("read tcp 10.60.2.57:47882->104.154.144.94:80: read: connection reset by peer"),
   105  		connReset: true,
   106  	}, {
   107  		name:      "error not matching",
   108  		err:       errors.New("dial tcp: lookup this.url.does.not.exist on 127.0.0.1:53: no such host"),
   109  		connReset: false,
   110  	}, {
   111  		name:      "nil error",
   112  		err:       nil,
   113  		connReset: false,
   114  	}} {
   115  		t.Run(tt.name, func(t *testing.T) {
   116  			if connReset := isConnectionReset(tt.err); tt.connReset != connReset {
   117  				t.Errorf("Expected connReset=%v, got %v", tt.connReset, connReset)
   118  			}
   119  		})
   120  	}
   121  }
   122  
   123  func TestTCPTimeout(t *testing.T) {
   124  	client := &http.Client{}
   125  
   126  	// We have no positive test for TCP timeout, but we do have a few negative tests.
   127  	for _, tt := range []struct {
   128  		name       string
   129  		url        string
   130  		tcpTimeout bool
   131  	}{{
   132  		name:       "nothing listening",
   133  		url:        "http://localhost:60001",
   134  		tcpTimeout: false,
   135  	}, {
   136  		name:       "dns error",
   137  		url:        "http://this.url.does.not.exist",
   138  		tcpTimeout: false,
   139  	}, {
   140  		name:       "google.com",
   141  		url:        "https://google.com",
   142  		tcpTimeout: false,
   143  	}} {
   144  		t.Run(tt.name, func(t *testing.T) {
   145  			req, _ := http.NewRequest(http.MethodGet, tt.url, nil)
   146  			resp, err := client.Do(req)
   147  			if resp != nil {
   148  				defer resp.Body.Close()
   149  			}
   150  			if tcpTimeout := isTCPTimeout(err); tt.tcpTimeout != tcpTimeout {
   151  				t.Errorf("Expected tcpTimeout=%v, got %v", tt.tcpTimeout, tcpTimeout)
   152  			}
   153  		})
   154  	}
   155  }