...

Source file src/edge-infra.dev/pkg/edge/device-registrar/services/device_discovery_service_test.go

Documentation: edge-infra.dev/pkg/edge/device-registrar/services

     1  package services
     2  
     3  import (
     4  	"context"
     5  	"net/http"
     6  	"net/http/httptest"
     7  	"testing"
     8  
     9  	"github.com/gin-gonic/gin"
    10  	"github.com/stretchr/testify/assert"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"sigs.k8s.io/controller-runtime/pkg/client"
    13  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    14  
    15  	api "edge-infra.dev/pkg/edge/device-registrar/api/v1alpha1"
    16  )
    17  
    18  func injectmockClientDiscover(router *gin.Engine, mockClient client.Client, t *testing.T) {
    19  	router.Use(
    20  		// Inject the mock client into the context
    21  		func(c *gin.Context) {
    22  			c.Set("k8sClient", mockClient)
    23  			c.Next()
    24  
    25  			k8sClient, exists := c.Get("k8sClient")
    26  
    27  			// Assert that k8sClient is not nil and exists
    28  			assert.True(t, exists, "k8sClient should exist in the context")
    29  			assert.NotNil(t, k8sClient, "k8sClient should not be nil")
    30  		},
    31  	)
    32  }
    33  
    34  func TestDiscovery(t *testing.T) {
    35  	router, scheme := setupTest()
    36  
    37  	discovery := api.Discovery{
    38  		ObjectMeta: metav1.ObjectMeta{
    39  			Name:      "example",
    40  			Namespace: "device-registrar-clients",
    41  		},
    42  		Spec: api.DiscoverySpec{
    43  			Name: "example-discovery",
    44  			URL:  "example-url.com/config",
    45  		},
    46  	}
    47  
    48  	device := api.ExternalDevice{
    49  		ObjectMeta: metav1.ObjectMeta{
    50  			Name:      "example",
    51  			Namespace: "device-registrar-clients",
    52  		},
    53  		Spec: api.ExternalDeviceSpec{
    54  			SN:   "my-serial-number",
    55  			Name: "test-device-name",
    56  		},
    57  	}
    58  
    59  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&discovery, &device).Build()
    60  
    61  	injectmockClientDiscover(router, mockClient, t)
    62  
    63  	// register endpoint
    64  	router.GET("/discover/:serviceName", DiscoverService)
    65  
    66  	// Create a new HTTP request without a payload
    67  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
    68  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name+OU=urn:SN:my-serial-number")
    69  
    70  	w := httptest.NewRecorder()
    71  	router.ServeHTTP(w, req)
    72  
    73  	// status code 200
    74  	assert.Equal(t, http.StatusOK, w.Code, "Expected status code 200")
    75  
    76  	assert.Contains(t, w.Body.String(), "name")
    77  	assert.Contains(t, w.Body.String(), "url")
    78  
    79  	assert.Equal(t, w.Body.String(), `{"name":"example-discovery","url":"example-url.com/config"}`)
    80  }
    81  
    82  func TestNoDiscovery(t *testing.T) {
    83  	router, scheme := setupTest()
    84  
    85  	device := api.ExternalDevice{
    86  		ObjectMeta: metav1.ObjectMeta{
    87  			Name:      "example",
    88  			Namespace: "device-registrar-clients",
    89  		},
    90  		Spec: api.ExternalDeviceSpec{
    91  			SN:   "my-serial-number",
    92  			Name: "test-device-name",
    93  		},
    94  	}
    95  
    96  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&device).Build()
    97  
    98  	injectmockClientDiscover(router, mockClient, t)
    99  
   100  	// register endpoint
   101  	router.GET("/discover/:serviceName", DiscoverService)
   102  
   103  	// Create a new HTTP request without a payload
   104  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
   105  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name+OU=urn:SN:my-serial-number")
   106  
   107  	w := httptest.NewRecorder()
   108  	router.ServeHTTP(w, req)
   109  
   110  	// status code 200
   111  	assert.Equal(t, http.StatusOK, w.Code, "Expected status code 200")
   112  
   113  	assert.Contains(t, w.Body.String(), "name")
   114  	assert.Contains(t, w.Body.String(), "url")
   115  
   116  	assert.Equal(t, w.Body.String(), `{"name":"example-discovery","url":null}`)
   117  }
   118  
   119  func TestMissingServiceName(t *testing.T) {
   120  	router, scheme := setupTest()
   121  
   122  	device := api.ExternalDevice{
   123  		ObjectMeta: metav1.ObjectMeta{
   124  			Name:      "example",
   125  			Namespace: "device-registrar-clients",
   126  		},
   127  		Spec: api.ExternalDeviceSpec{
   128  			SN:   "my-serial-number",
   129  			Name: "test-device-name",
   130  		},
   131  	}
   132  
   133  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&device).Build()
   134  
   135  	injectmockClientDiscover(router, mockClient, t)
   136  
   137  	// register endpoint
   138  	router.GET("/discover/:serviceName", DiscoverService)
   139  
   140  	// Create a new HTTP request without a payload
   141  	req, _ := http.NewRequest(http.MethodGet, "/discover/", nil)
   142  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name+OU=urn:SN:my-serial-number")
   143  
   144  	w := httptest.NewRecorder()
   145  	router.ServeHTTP(w, req)
   146  
   147  	assert.Equal(t, w.Body.String(), "404 page not found")
   148  }
   149  
   150  func TestEmptyDiscoveryList(t *testing.T) {
   151  	router, scheme := setupTest()
   152  	device := api.ExternalDevice{
   153  		ObjectMeta: metav1.ObjectMeta{
   154  			Name:      "example",
   155  			Namespace: "device-registrar-clients",
   156  		},
   157  		Spec: api.ExternalDeviceSpec{
   158  			SN:   "my-serial-number",
   159  			Name: "test-device-name",
   160  		},
   161  	}
   162  
   163  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&device).Build()
   164  
   165  	injectmockClientDiscover(router, mockClient, t)
   166  
   167  	// register endpoint
   168  	router.GET("/discover/:serviceName", DiscoverService)
   169  
   170  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
   171  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name+OU=urn:SN:my-serial-number")
   172  
   173  	w := httptest.NewRecorder()
   174  	router.ServeHTTP(w, req)
   175  
   176  	// status code 200
   177  	assert.Equal(t, http.StatusOK, w.Code, "Expected status code 200")
   178  
   179  	assert.Equal(t, w.Body.String(), `{"name":"example-discovery","url":null}`)
   180  }
   181  func TestDiscoveryNoHeader(t *testing.T) {
   182  	router, scheme := setupTest()
   183  	mockClient := fake.NewClientBuilder().WithScheme(scheme).Build()
   184  
   185  	injectmockClientDiscover(router, mockClient, t)
   186  
   187  	// register endpoint
   188  	router.GET("/discover/:serviceName", DiscoverService)
   189  
   190  	// Create a new HTTP request without a payload
   191  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
   192  
   193  	w := httptest.NewRecorder()
   194  	router.ServeHTTP(w, req)
   195  
   196  	// status code 401
   197  	assert.Equal(t, http.StatusUnauthorized, w.Code, "Expected status code 401")
   198  
   199  	assert.Equal(t, w.Body.String(), `{"error":"X-Client-DN is required"}`)
   200  }
   201  
   202  func TestDiscoveryIncorrectSN(t *testing.T) {
   203  	router, scheme := setupTest()
   204  
   205  	device := api.ExternalDevice{
   206  		ObjectMeta: metav1.ObjectMeta{
   207  			Name:      "example",
   208  			Namespace: "device-registrar-clients",
   209  		},
   210  		Spec: api.ExternalDeviceSpec{
   211  			SN:   "my-serial-number-different",
   212  			Name: "test-device-name",
   213  		},
   214  	}
   215  
   216  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&device).Build()
   217  
   218  	injectmockClientDiscover(router, mockClient, t)
   219  
   220  	// register endpoint
   221  	router.GET("/discover/:serviceName", DiscoverService)
   222  
   223  	// Create a new HTTP request without a payload
   224  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
   225  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name+OU=urn:SN:my-serial-number")
   226  
   227  	w := httptest.NewRecorder()
   228  	router.ServeHTTP(w, req)
   229  
   230  	// status code 401
   231  	assert.Equal(t, http.StatusUnauthorized, w.Code, "Expected status code 401")
   232  
   233  	assert.Equal(t, w.Body.String(), `{"error":"Unauthorized Serial Number"}`)
   234  }
   235  
   236  func TestDiscoveryNoSN(t *testing.T) {
   237  	router, scheme := setupTest()
   238  
   239  	mockClient := fake.NewClientBuilder().WithScheme(scheme).Build()
   240  
   241  	injectmockClientDiscover(router, mockClient, t)
   242  
   243  	// register endpoint
   244  	router.GET("/discover/:serviceName", DiscoverService)
   245  
   246  	// Create a new HTTP request without a payload
   247  	req, _ := http.NewRequest(http.MethodGet, "/discover/example-discovery", nil)
   248  	req.Header.Set("X-Client-DN", "OU=urn:storeID:my-store-id=urn:deviceName:test-device-name")
   249  
   250  	w := httptest.NewRecorder()
   251  	router.ServeHTTP(w, req)
   252  
   253  	// status code 401
   254  	assert.Equal(t, http.StatusUnauthorized, w.Code, "Expected status code 401")
   255  
   256  	assert.Equal(t, w.Body.String(), `{"error":"Serial Number is required in X-Client-DN"}`)
   257  }
   258  
   259  func TestParseSN(t *testing.T) {
   260  	sn := parseSerialNumber("OU=urn:storeID:my-store-id+OU=urn:deviceName:test-device-name+OU=urn:SN:a1b2c3d4")
   261  	assert.Equal(t, sn, "a1b2c3d4")
   262  }
   263  
   264  func TestIsSNAuthorized(t *testing.T) {
   265  	_, scheme := setupTest()
   266  
   267  	device := api.ExternalDevice{
   268  		ObjectMeta: metav1.ObjectMeta{
   269  			Name:      "example",
   270  			Namespace: "device-registrar-clients",
   271  		},
   272  		Spec: api.ExternalDeviceSpec{
   273  			SN:   "my-serial-number",
   274  			Name: "test-device-name",
   275  		},
   276  	}
   277  
   278  	ctx := context.Background()
   279  	mockClient := fake.NewClientBuilder().WithScheme(scheme).WithObjects(&device).Build()
   280  
   281  	assert.True(t, isSNAuthorized(ctx, mockClient, "my-serial-number"))
   282  	assert.False(t, isSNAuthorized(ctx, mockClient, "different-serial-number"))
   283  }
   284  

View as plain text