github.com/yrj2011/jx-test-infra@v0.0.0-20190529031832-7a2065ee98eb/boskos/boskos_test.go (about)

     1  /*
     2  Copyright 2017 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 main
    18  
    19  import (
    20  	"encoding/json"
    21  	"net/http"
    22  	"net/http/httptest"
    23  	"net/url"
    24  	"reflect"
    25  	"testing"
    26  	"time"
    27  
    28  	"k8s.io/test-infra/boskos/common"
    29  	"k8s.io/test-infra/boskos/crds"
    30  	"k8s.io/test-infra/boskos/ranch"
    31  )
    32  
    33  func MakeTestRanch(resources []common.Resource) *ranch.Ranch {
    34  	resourceClient := crds.NewTestResourceClient()
    35  	s, _ := ranch.NewStorage(crds.NewCRDStorage(resourceClient), "")
    36  	for _, r := range resources {
    37  		s.AddResource(r)
    38  	}
    39  	r, _ := ranch.NewRanch("", s)
    40  	return r
    41  }
    42  
    43  func TestAcquire(t *testing.T) {
    44  	var testcases = []struct {
    45  		name      string
    46  		resources []common.Resource
    47  		path      string
    48  		code      int
    49  		method    string
    50  	}{
    51  		{
    52  			name:      "reject get method",
    53  			resources: []common.Resource{},
    54  			path:      "?type=t&state=s&dest=d&owner=o",
    55  			code:      http.StatusMethodNotAllowed,
    56  			method:    http.MethodGet,
    57  		},
    58  		{
    59  			name:      "reject request no arg",
    60  			resources: []common.Resource{},
    61  			path:      "",
    62  			code:      http.StatusBadRequest,
    63  			method:    http.MethodPost,
    64  		},
    65  		{
    66  			name:      "reject request missing type",
    67  			resources: []common.Resource{},
    68  			path:      "?state=s&dest=d&owner=o",
    69  			code:      http.StatusBadRequest,
    70  			method:    http.MethodPost,
    71  		},
    72  		{
    73  			name:      "reject request missing state",
    74  			resources: []common.Resource{},
    75  			path:      "?type=t&dest=d&owner=o",
    76  			code:      http.StatusBadRequest,
    77  			method:    http.MethodPost,
    78  		},
    79  		{
    80  			name:      "reject request missing owner",
    81  			resources: []common.Resource{},
    82  			path:      "?type=t&state=s&dest=d",
    83  			code:      http.StatusBadRequest,
    84  			method:    http.MethodPost,
    85  		},
    86  		{
    87  			name:      "reject request missing dest",
    88  			resources: []common.Resource{},
    89  			path:      "?type=t&state=s&owner=o",
    90  			code:      http.StatusBadRequest,
    91  			method:    http.MethodPost,
    92  		},
    93  		{
    94  			name:      "ranch has no resource",
    95  			resources: []common.Resource{},
    96  			path:      "?type=t&state=s&dest=d&owner=o",
    97  			code:      http.StatusNotFound,
    98  			method:    http.MethodPost,
    99  		},
   100  		{
   101  			name: "no match type",
   102  			resources: []common.Resource{
   103  				{
   104  					Name:  "res",
   105  					Type:  "wrong",
   106  					State: "s",
   107  					Owner: "",
   108  				},
   109  			},
   110  			path:   "?type=t&state=s&dest=d&owner=o",
   111  			code:   http.StatusNotFound,
   112  			method: http.MethodPost,
   113  		},
   114  		{
   115  			name: "no match state",
   116  			resources: []common.Resource{
   117  				{
   118  					Name:  "res",
   119  					Type:  "t",
   120  					State: "wrong",
   121  					Owner: "",
   122  				},
   123  			},
   124  			path:   "?type=t&state=s&dest=d&owner=o",
   125  			code:   http.StatusNotFound,
   126  			method: http.MethodPost,
   127  		},
   128  		{
   129  			name: "busy",
   130  			resources: []common.Resource{
   131  				{
   132  					Name:  "res",
   133  					Type:  "t",
   134  					State: "s",
   135  					Owner: "user",
   136  				},
   137  			},
   138  			path:   "?type=t&state=s&dest=d&owner=o",
   139  			code:   http.StatusNotFound,
   140  			method: http.MethodPost,
   141  		},
   142  		{
   143  			name: "ok",
   144  			resources: []common.Resource{
   145  				{
   146  					Name:  "res",
   147  					Type:  "t",
   148  					State: "s",
   149  					Owner: "",
   150  				},
   151  			},
   152  			path:   "?type=t&state=s&dest=d&owner=o",
   153  			code:   http.StatusOK,
   154  			method: http.MethodPost,
   155  		},
   156  	}
   157  
   158  	for _, tc := range testcases {
   159  		c := MakeTestRanch(tc.resources)
   160  		handler := handleAcquire(c)
   161  		req, err := http.NewRequest(tc.method, "", nil)
   162  		if err != nil {
   163  			t.Fatalf("Error making request: %v", err)
   164  		}
   165  		u, err := url.Parse(tc.path)
   166  		if err != nil {
   167  			t.Fatalf("Error parsing URL: %v", err)
   168  		}
   169  		req.URL = u
   170  		rr := httptest.NewRecorder()
   171  		handler.ServeHTTP(rr, req)
   172  		if rr.Code != tc.code {
   173  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   174  		}
   175  
   176  		if rr.Code == http.StatusOK {
   177  			var data common.Resource
   178  			json.Unmarshal(rr.Body.Bytes(), &data)
   179  			if data.Name != "res" {
   180  				t.Errorf("%s - Got res %v, expect res", tc.name, data.Name)
   181  			}
   182  
   183  			if data.State != "d" {
   184  				t.Errorf("%s - Got state %v, expect d", tc.name, data.State)
   185  			}
   186  
   187  			resources, err := c.Storage.GetResources()
   188  			if err != nil {
   189  				t.Error("cannot get resources")
   190  				continue
   191  			}
   192  			if resources[0].Owner != "o" {
   193  				t.Errorf("%s - Wrong owner. Got %v, expect o", tc.name, resources[0].Owner)
   194  			}
   195  		}
   196  	}
   197  }
   198  
   199  func TestRelease(t *testing.T) {
   200  	var testcases = []struct {
   201  		name      string
   202  		resources []common.Resource
   203  		path      string
   204  		code      int
   205  		method    string
   206  	}{
   207  		{
   208  			name:      "reject get method",
   209  			resources: []common.Resource{},
   210  			path:      "?name=res&dest=d&owner=foo",
   211  			code:      http.StatusMethodNotAllowed,
   212  			method:    http.MethodGet,
   213  		},
   214  		{
   215  			name:      "reject request no arg",
   216  			resources: []common.Resource{},
   217  			path:      "",
   218  			code:      http.StatusBadRequest,
   219  			method:    http.MethodPost,
   220  		},
   221  		{
   222  			name:      "reject request missing name",
   223  			resources: []common.Resource{},
   224  			path:      "?dest=d&owner=foo",
   225  			code:      http.StatusBadRequest,
   226  			method:    http.MethodPost,
   227  		},
   228  		{
   229  			name:      "reject request missing dest",
   230  			resources: []common.Resource{},
   231  			path:      "?name=res&owner=foo",
   232  			code:      http.StatusBadRequest,
   233  			method:    http.MethodPost,
   234  		},
   235  		{
   236  			name:      "reject request missing owner",
   237  			resources: []common.Resource{},
   238  			path:      "?name=res&dest=d",
   239  			code:      http.StatusBadRequest,
   240  			method:    http.MethodPost,
   241  		},
   242  		{
   243  			name:      "ranch has no resource",
   244  			resources: []common.Resource{},
   245  			path:      "?name=res&dest=d&owner=foo",
   246  			code:      http.StatusNotFound,
   247  			method:    http.MethodPost,
   248  		},
   249  		{
   250  			name: "wrong owner",
   251  			resources: []common.Resource{
   252  				{
   253  					Name:  "res",
   254  					Type:  "t",
   255  					State: "s",
   256  					Owner: "merlin",
   257  				},
   258  			},
   259  			path:   "?name=res&dest=d&owner=foo",
   260  			code:   http.StatusUnauthorized,
   261  			method: http.MethodPost,
   262  		},
   263  		{
   264  			name: "no match name",
   265  			resources: []common.Resource{
   266  				{
   267  					Name:  "foo",
   268  					Type:  "t",
   269  					State: "s",
   270  					Owner: "merlin",
   271  				},
   272  			},
   273  			path:   "?name=res&dest=d&owner=merlin",
   274  			code:   http.StatusNotFound,
   275  			method: http.MethodPost,
   276  		},
   277  		{
   278  			name: "ok",
   279  			resources: []common.Resource{
   280  				{
   281  					Name:  "res",
   282  					Type:  "t",
   283  					State: "s",
   284  					Owner: "merlin",
   285  				},
   286  			},
   287  			path:   "?name=res&dest=d&owner=merlin",
   288  			code:   http.StatusOK,
   289  			method: http.MethodPost,
   290  		},
   291  	}
   292  
   293  	for _, tc := range testcases {
   294  		c := MakeTestRanch(tc.resources)
   295  		handler := handleRelease(c)
   296  		req, err := http.NewRequest(tc.method, "", nil)
   297  		if err != nil {
   298  			t.Fatalf("Error making request: %v", err)
   299  		}
   300  		u, err := url.Parse(tc.path)
   301  		if err != nil {
   302  			t.Fatalf("Error parsing URL: %v", err)
   303  		}
   304  		req.URL = u
   305  		rr := httptest.NewRecorder()
   306  		handler.ServeHTTP(rr, req)
   307  		if rr.Code != tc.code {
   308  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   309  		}
   310  
   311  		if rr.Code == http.StatusOK {
   312  			resources, err := c.Storage.GetResources()
   313  			if err != nil {
   314  				t.Error("cannot get resources")
   315  				continue
   316  			}
   317  			if resources[0].State != "d" {
   318  				t.Errorf("%s - Wrong state. Got %v, expect d", tc.name, resources[0].State)
   319  			}
   320  
   321  			if resources[0].Owner != "" {
   322  				t.Errorf("%s - Wrong owner. Got %v, expect empty", tc.name, resources[0].Owner)
   323  			}
   324  		}
   325  	}
   326  }
   327  
   328  func TestReset(t *testing.T) {
   329  	var testcases = []struct {
   330  		name       string
   331  		resources  []common.Resource
   332  		path       string
   333  		code       int
   334  		method     string
   335  		hasContent bool
   336  	}{
   337  		{
   338  			name:      "reject get method",
   339  			resources: []common.Resource{},
   340  			path:      "?type=t&state=s&expire=10m&dest=d",
   341  			code:      http.StatusMethodNotAllowed,
   342  			method:    http.MethodGet,
   343  		},
   344  		{
   345  			name:      "reject request no arg",
   346  			resources: []common.Resource{},
   347  			path:      "",
   348  			code:      http.StatusBadRequest,
   349  			method:    http.MethodPost,
   350  		},
   351  		{
   352  			name:      "reject request missing type",
   353  			resources: []common.Resource{},
   354  			path:      "?state=s&expire=10m&dest=d",
   355  			code:      http.StatusBadRequest,
   356  			method:    http.MethodPost,
   357  		},
   358  		{
   359  			name:      "reject request missing state",
   360  			resources: []common.Resource{},
   361  			path:      "?type=t&expire=10m&dest=d",
   362  			code:      http.StatusBadRequest,
   363  			method:    http.MethodPost,
   364  		},
   365  		{
   366  			name:      "reject request missing expire",
   367  			resources: []common.Resource{},
   368  			path:      "?type=t&state=s&dest=d",
   369  			code:      http.StatusBadRequest,
   370  			method:    http.MethodPost,
   371  		},
   372  		{
   373  			name:      "reject request missing dest",
   374  			resources: []common.Resource{},
   375  			path:      "?type=t&state=s&expire=10m",
   376  			code:      http.StatusBadRequest,
   377  			method:    http.MethodPost,
   378  		},
   379  		{
   380  			name:      "reject request bad expire",
   381  			resources: []common.Resource{},
   382  			path:      "?type=t&state=s&expire=woooo&dest=d",
   383  			code:      http.StatusBadRequest,
   384  			method:    http.MethodPost,
   385  		},
   386  		{
   387  			name: "empty - has no owner",
   388  			resources: []common.Resource{
   389  				{
   390  					Name:       "res",
   391  					Type:       "t",
   392  					State:      "s",
   393  					Owner:      "",
   394  					LastUpdate: time.Now().Add(-time.Minute * 20),
   395  				},
   396  			},
   397  			path:   "?type=t&state=s&expire=10m&dest=d",
   398  			code:   http.StatusOK,
   399  			method: http.MethodPost,
   400  		},
   401  		{
   402  			name: "empty - not expire",
   403  			resources: []common.Resource{
   404  				{
   405  					Name:       "res",
   406  					Type:       "t",
   407  					State:      "s",
   408  					Owner:      "",
   409  					LastUpdate: time.Now(),
   410  				},
   411  			},
   412  			path:   "?type=t&state=s&expire=10m&dest=d",
   413  			code:   http.StatusOK,
   414  			method: http.MethodPost,
   415  		},
   416  		{
   417  			name: "empty - no match type",
   418  			resources: []common.Resource{
   419  				{
   420  					Name:       "res",
   421  					Type:       "wrong",
   422  					State:      "s",
   423  					Owner:      "",
   424  					LastUpdate: time.Now().Add(-time.Minute * 20),
   425  				},
   426  			},
   427  			path:   "?type=t&state=s&expire=10m&dest=d",
   428  			code:   http.StatusOK,
   429  			method: http.MethodPost,
   430  		},
   431  		{
   432  			name: "empty - no match state",
   433  			resources: []common.Resource{
   434  				{
   435  					Name:       "res",
   436  					Type:       "t",
   437  					State:      "wrong",
   438  					Owner:      "",
   439  					LastUpdate: time.Now().Add(-time.Minute * 20),
   440  				},
   441  			},
   442  			path:   "?type=t&state=s&expire=10m&dest=d",
   443  			code:   http.StatusOK,
   444  			method: http.MethodPost,
   445  		},
   446  		{
   447  			name: "ok",
   448  			resources: []common.Resource{
   449  				{
   450  					Name:       "res",
   451  					Type:       "t",
   452  					State:      "s",
   453  					Owner:      "user",
   454  					LastUpdate: time.Now().Add(-time.Minute * 20),
   455  				},
   456  			},
   457  			path:       "?type=t&state=s&expire=10m&dest=d",
   458  			code:       http.StatusOK,
   459  			method:     http.MethodPost,
   460  			hasContent: true,
   461  		},
   462  	}
   463  
   464  	for _, tc := range testcases {
   465  		c := MakeTestRanch(tc.resources)
   466  		handler := handleReset(c)
   467  		req, err := http.NewRequest(tc.method, "", nil)
   468  		if err != nil {
   469  			t.Fatalf("Error making request: %v", err)
   470  		}
   471  		u, err := url.Parse(tc.path)
   472  		if err != nil {
   473  			t.Fatalf("Error parsing URL: %v", err)
   474  		}
   475  		req.URL = u
   476  		rr := httptest.NewRecorder()
   477  		handler.ServeHTTP(rr, req)
   478  		if rr.Code != tc.code {
   479  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   480  		}
   481  
   482  		if rr.Code == http.StatusOK {
   483  			rmap := make(map[string]string)
   484  			json.Unmarshal(rr.Body.Bytes(), &rmap)
   485  			if !tc.hasContent {
   486  				if len(rmap) != 0 {
   487  					t.Errorf("%s - Expect empty map. Got %v", tc.name, rmap)
   488  				}
   489  			} else {
   490  				if owner, ok := rmap["res"]; !ok || owner != "user" {
   491  					t.Errorf("%s - Expect res - user. Got %v", tc.name, rmap)
   492  				}
   493  			}
   494  		}
   495  	}
   496  }
   497  
   498  func TestUpdate(t *testing.T) {
   499  	FakeNow := time.Now()
   500  
   501  	var testcases = []struct {
   502  		name      string
   503  		resources []common.Resource
   504  		path      string
   505  		code      int
   506  		method    string
   507  	}{
   508  		{
   509  			name:      "reject get method",
   510  			resources: []common.Resource{},
   511  			path:      "?name=foo",
   512  			code:      http.StatusMethodNotAllowed,
   513  			method:    http.MethodGet,
   514  		},
   515  		{
   516  			name:      "reject request no arg",
   517  			resources: []common.Resource{},
   518  			path:      "",
   519  			code:      http.StatusBadRequest,
   520  			method:    http.MethodPost,
   521  		},
   522  		{
   523  			name:      "reject request missing name",
   524  			resources: []common.Resource{},
   525  			path:      "?state=s&owner=merlin",
   526  			code:      http.StatusBadRequest,
   527  			method:    http.MethodPost,
   528  		},
   529  		{
   530  			name:      "reject request missing owner",
   531  			resources: []common.Resource{},
   532  			path:      "?name=res&state=s",
   533  			code:      http.StatusBadRequest,
   534  			method:    http.MethodPost,
   535  		},
   536  		{
   537  			name:      "reject request missing state",
   538  			resources: []common.Resource{},
   539  			path:      "?name=res&owner=merlin",
   540  			code:      http.StatusBadRequest,
   541  			method:    http.MethodPost,
   542  		},
   543  		{
   544  			name:      "ranch has no resource",
   545  			resources: []common.Resource{},
   546  			path:      "?name=res&state=s&owner=merlin",
   547  			code:      http.StatusNotFound,
   548  			method:    http.MethodPost,
   549  		},
   550  		{
   551  			name: "wrong owner",
   552  			resources: []common.Resource{
   553  				{
   554  					Name:  "res",
   555  					Type:  "t",
   556  					State: "s",
   557  					Owner: "evil",
   558  				},
   559  			},
   560  			path:   "?name=res&state=s&owner=merlin",
   561  			code:   http.StatusUnauthorized,
   562  			method: http.MethodPost,
   563  		},
   564  		{
   565  			name: "wrong state",
   566  			resources: []common.Resource{
   567  				{
   568  					Name:  "res",
   569  					Type:  "t",
   570  					State: "s",
   571  					Owner: "merlin",
   572  				},
   573  			},
   574  			path:   "?name=res&state=d&owner=merlin",
   575  			code:   http.StatusConflict,
   576  			method: http.MethodPost,
   577  		},
   578  		{
   579  			name: "no matched resource",
   580  			resources: []common.Resource{
   581  				{
   582  					Name:  "res",
   583  					Type:  "t",
   584  					State: "s",
   585  					Owner: "merlin",
   586  				},
   587  			},
   588  			path:   "?name=foo&state=s&owner=merlin",
   589  			code:   http.StatusNotFound,
   590  			method: http.MethodPost,
   591  		},
   592  		{
   593  			name: "ok",
   594  			resources: []common.Resource{
   595  				{
   596  					Name:       "res",
   597  					Type:       "t",
   598  					State:      "s",
   599  					Owner:      "merlin",
   600  					LastUpdate: FakeNow,
   601  				},
   602  			},
   603  			path:   "?name=res&state=s&owner=merlin",
   604  			code:   http.StatusOK,
   605  			method: http.MethodPost,
   606  		},
   607  		{
   608  			name: "ok",
   609  			resources: []common.Resource{
   610  				{
   611  					Name:       "res",
   612  					Type:       "t",
   613  					State:      "s",
   614  					Owner:      "merlin",
   615  					LastUpdate: FakeNow,
   616  				},
   617  			},
   618  			path:   "?name=res&state=s&owner=merlin",
   619  			code:   http.StatusOK,
   620  			method: http.MethodPost,
   621  		},
   622  	}
   623  
   624  	for _, tc := range testcases {
   625  		c := MakeTestRanch(tc.resources)
   626  		handler := handleUpdate(c)
   627  		req, err := http.NewRequest(tc.method, "", nil)
   628  		if err != nil {
   629  			t.Fatalf("Error making request: %v", err)
   630  		}
   631  		u, err := url.Parse(tc.path)
   632  		if err != nil {
   633  			t.Fatalf("Error parsing URL: %v", err)
   634  		}
   635  		req.URL = u
   636  		rr := httptest.NewRecorder()
   637  		handler.ServeHTTP(rr, req)
   638  		if rr.Code != tc.code {
   639  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   640  		}
   641  
   642  		if rr.Code == http.StatusOK {
   643  			resources, err := c.Storage.GetResources()
   644  			if err != nil {
   645  				t.Error("cannot get resources")
   646  				continue
   647  			}
   648  			if resources[0].LastUpdate == FakeNow {
   649  				t.Errorf("%s - Timestamp is not updated!", tc.name)
   650  			}
   651  		}
   652  	}
   653  }
   654  
   655  func TestGetMetric(t *testing.T) {
   656  	var testcases = []struct {
   657  		name      string
   658  		resources []common.Resource
   659  		path      string
   660  		code      int
   661  		method    string
   662  		expect    common.Metric
   663  	}{
   664  		{
   665  			name:      "reject none-get method",
   666  			resources: []common.Resource{},
   667  			path:      "?type=t",
   668  			code:      http.StatusMethodNotAllowed,
   669  			method:    http.MethodPost,
   670  		},
   671  		{
   672  			name:      "reject request no type",
   673  			resources: []common.Resource{},
   674  			path:      "",
   675  			code:      http.StatusBadRequest,
   676  			method:    http.MethodGet,
   677  		},
   678  		{
   679  			name:      "ranch has no resource",
   680  			resources: []common.Resource{},
   681  			path:      "?type=t",
   682  			code:      http.StatusNotFound,
   683  			method:    http.MethodGet,
   684  		},
   685  		{
   686  			name: "wrong type",
   687  			resources: []common.Resource{
   688  				{
   689  					Name:  "res",
   690  					Type:  "t",
   691  					State: "s",
   692  					Owner: "evil",
   693  				},
   694  			},
   695  			path:   "?type=foo",
   696  			code:   http.StatusNotFound,
   697  			method: http.MethodGet,
   698  		},
   699  		{
   700  			name: "ok",
   701  			resources: []common.Resource{
   702  				{
   703  					Name:  "res",
   704  					Type:  "t",
   705  					State: "s",
   706  					Owner: "merlin",
   707  				},
   708  			},
   709  			path:   "?type=t",
   710  			code:   http.StatusOK,
   711  			method: http.MethodGet,
   712  			expect: common.Metric{
   713  				Type: "t",
   714  				Current: map[string]int{
   715  					"s": 1,
   716  				},
   717  				Owners: map[string]int{
   718  					"merlin": 1,
   719  				},
   720  			},
   721  		},
   722  	}
   723  
   724  	for _, tc := range testcases {
   725  		c := MakeTestRanch(tc.resources)
   726  		handler := handleMetric(c)
   727  		req, err := http.NewRequest(tc.method, "", nil)
   728  		if err != nil {
   729  			t.Fatalf("Error making request: %v", err)
   730  		}
   731  		u, err := url.Parse(tc.path)
   732  		if err != nil {
   733  			t.Fatalf("Error parsing URL: %v", err)
   734  		}
   735  		req.URL = u
   736  		rr := httptest.NewRecorder()
   737  		handler.ServeHTTP(rr, req)
   738  		if rr.Code != tc.code {
   739  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   740  		}
   741  
   742  		if rr.Code == http.StatusOK {
   743  			var metric common.Metric
   744  			if err := json.Unmarshal(rr.Body.Bytes(), &metric); err != nil {
   745  				t.Errorf("%s - Fail to unmarshal body - %s", tc.name, err)
   746  			}
   747  			if !reflect.DeepEqual(metric, tc.expect) {
   748  				t.Errorf("%s - wrong metric, got %v, want %v", tc.name, metric, tc.expect)
   749  			}
   750  		}
   751  	}
   752  }
   753  
   754  func TestDefault(t *testing.T) {
   755  	var testcases = []struct {
   756  		name string
   757  		code int
   758  	}{
   759  		{
   760  			name: "empty",
   761  			code: http.StatusOK,
   762  		},
   763  	}
   764  
   765  	for _, tc := range testcases {
   766  		handler := handleDefault(nil)
   767  		req, err := http.NewRequest(http.MethodGet, "", nil)
   768  		if err != nil {
   769  			t.Fatalf("Error making request: %v", err)
   770  		}
   771  		rr := httptest.NewRecorder()
   772  		handler.ServeHTTP(rr, req)
   773  		if rr.Code != tc.code {
   774  			t.Errorf("%s - Wrong error code. Got %v, expect %v", tc.name, rr.Code, tc.code)
   775  		}
   776  	}
   777  }
   778  
   779  func TestConfig(t *testing.T) {
   780  	resources, err := ranch.ParseConfig("resources.yaml")
   781  	if err != nil {
   782  		t.Errorf("parseConfig error: %v", err)
   783  	}
   784  
   785  	if len(resources) == 0 {
   786  		t.Errorf("empty data")
   787  	}
   788  	resourceNames := map[string]bool{}
   789  
   790  	for _, p := range resources {
   791  		if p.Name == "" {
   792  			t.Errorf("empty resource name: %v", p.Name)
   793  		}
   794  
   795  		if _, ok := resourceNames[p.Name]; ok {
   796  			t.Errorf("duplicated resource name: %v", p.Name)
   797  		} else {
   798  			resourceNames[p.Name] = true
   799  		}
   800  	}
   801  }