github.com/cilium/cilium@v1.16.2/pkg/service/healthserver/healthserver_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package healthserver
     5  
     6  import (
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/google/go-cmp/cmp"
    12  	"github.com/stretchr/testify/require"
    13  )
    14  
    15  func TestServiceHealthServer_UpsertService(t *testing.T) {
    16  	f := NewMockHealthHTTPServerFactory()
    17  	h := WithHealthHTTPServerFactory(f)
    18  
    19  	// Insert svc1
    20  	h.UpsertService(1, "default", "svc1", 1, 32000)
    21  	require.Equal(t, "default", f.ServiceByPort(32000).Service.Namespace)
    22  	require.Equal(t, "svc1", f.ServiceByPort(32000).Service.Name)
    23  	require.Equal(t, 1, f.ServiceByPort(32000).LocalEndpoints)
    24  
    25  	// Disable svc1 port
    26  	h.UpsertService(1, "default", "svc1", 1, 0)
    27  	require.Nil(t, f.ServiceByPort(32000))
    28  
    29  	// Re-enable svc1 port
    30  	h.UpsertService(1, "default", "svc1", 1, 32000)
    31  	require.Equal(t, "default", f.ServiceByPort(32000).Service.Namespace)
    32  	require.Equal(t, "svc1", f.ServiceByPort(32000).Service.Name)
    33  	require.Equal(t, 1, f.ServiceByPort(32000).LocalEndpoints)
    34  
    35  	// Change svc1 port
    36  	h.UpsertService(1, "default", "svc1", 2, 32001)
    37  	require.Nil(t, f.ServiceByPort(32000))
    38  	require.Equal(t, "default", f.ServiceByPort(32001).Service.Namespace)
    39  	require.Equal(t, "svc1", f.ServiceByPort(32001).Service.Name)
    40  	require.Equal(t, 2, f.ServiceByPort(32001).LocalEndpoints)
    41  
    42  	// Update svc1 count
    43  	h.UpsertService(1, "default", "svc1", 3, 32001)
    44  	require.Equal(t, "default", f.ServiceByPort(32001).Service.Namespace)
    45  	require.Equal(t, "svc1", f.ServiceByPort(32001).Service.Name)
    46  	require.Equal(t, 3, f.ServiceByPort(32001).LocalEndpoints)
    47  
    48  	// Add svc1 clone (uses same port, must be ref-counted)
    49  	h.UpsertService(100, "default", "svc1", 3, 32001)
    50  	require.Equal(t, "default", f.ServiceByPort(32001).Service.Namespace)
    51  	require.Equal(t, "svc1", f.ServiceByPort(32001).Service.Name)
    52  	require.Equal(t, 3, f.ServiceByPort(32001).LocalEndpoints)
    53  
    54  	// Insert svc2
    55  	h.UpsertService(2, "default", "svc2", 0, 32002)
    56  	require.Equal(t, "default", f.ServiceByPort(32002).Service.Namespace)
    57  	require.Equal(t, "svc2", f.ServiceByPort(32002).Service.Name)
    58  	require.Equal(t, 0, f.ServiceByPort(32002).LocalEndpoints)
    59  
    60  	// Delete svc1 clone
    61  	h.DeleteService(100)
    62  	require.NotNil(t, f.ServiceByPort(32001))
    63  	require.NotNil(t, f.ServiceByPort(32002))
    64  
    65  	// Delete svc1
    66  	h.DeleteService(1)
    67  	require.Nil(t, f.ServiceByPort(32001))
    68  	require.NotNil(t, f.ServiceByPort(32002))
    69  
    70  	// Delete svc2
    71  	h.DeleteService(2)
    72  	require.Nil(t, f.ServiceByPort(32001))
    73  	require.Nil(t, f.ServiceByPort(32002))
    74  }
    75  
    76  func Test_httpHealthServer_ServeHTTP(t *testing.T) {
    77  	h := &httpHealthServer{}
    78  	ts := httptest.NewServer(h)
    79  	defer ts.Close()
    80  
    81  	// Set local endpoints, server must respond with HTTP 200
    82  	h.updateService(NewService("default", "svc", 2))
    83  	resp, err := http.Get(ts.URL)
    84  	require.Nil(t, err)
    85  	require.Equal(t, http.StatusOK, resp.StatusCode)
    86  	assertRespHeader(t, resp, "Content-Type", "application/json")
    87  	assertRespHeader(t, resp, "X-Content-Type-Options", "nosniff")
    88  	assertRespHeader(t, resp, "X-Load-Balancing-Endpoint-Weight", "2")
    89  	resp.Body.Close()
    90  
    91  	// Remove local endpoints, server must respond with HTTP 503
    92  	h.updateService(NewService("default", "svc", 0))
    93  	resp, err = http.Get(ts.URL)
    94  	require.Nil(t, err)
    95  	require.Equal(t, http.StatusServiceUnavailable, resp.StatusCode)
    96  	resp.Body.Close()
    97  }
    98  
    99  func assertRespHeader(t *testing.T, resp *http.Response, key, val string) {
   100  	if !cmp.Equal(resp.Header[key], []string{val}) {
   101  		t.Errorf("Want response header: %q: %q, got: %q, %q,", key, []string{val}, key, resp.Header[key])
   102  	}
   103  }