github.com/abayer/test-infra@v0.0.5/prow/hook/server_test.go (about)

     1  /*
     2  Copyright 2016 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 hook
    18  
    19  import (
    20  	"net/http"
    21  	"net/http/httptest"
    22  	"reflect"
    23  	"strings"
    24  	"testing"
    25  
    26  	"k8s.io/test-infra/prow/plugins"
    27  )
    28  
    29  func TestServeHTTPErrors(t *testing.T) {
    30  	metrics := NewMetrics()
    31  	pa := &plugins.PluginAgent{}
    32  	pa.Set(&plugins.Configuration{})
    33  
    34  	getSecret := func() []byte {
    35  		return []byte("abc")
    36  	}
    37  
    38  	s := &Server{
    39  		Metrics:        metrics,
    40  		Plugins:        pa,
    41  		TokenGenerator: getSecret,
    42  	}
    43  	// This is the SHA1 signature for payload "{}" and signature "abc"
    44  	// echo -n '{}' | openssl dgst -sha1 -hmac abc
    45  	const hmac string = "sha1=db5c76f4264d0ad96cf21baec394964b4b8ce580"
    46  	const body string = "{}"
    47  	var testcases = []struct {
    48  		name string
    49  
    50  		Method string
    51  		Header map[string]string
    52  		Body   string
    53  		Code   int
    54  	}{
    55  		{
    56  			name: "Delete",
    57  
    58  			Method: http.MethodDelete,
    59  			Header: map[string]string{
    60  				"X-GitHub-Event":    "ping",
    61  				"X-GitHub-Delivery": "I am unique",
    62  				"X-Hub-Signature":   hmac,
    63  				"content-type":      "application/json",
    64  			},
    65  			Body: body,
    66  			Code: http.StatusMethodNotAllowed,
    67  		},
    68  		{
    69  			name: "No event",
    70  
    71  			Method: http.MethodPost,
    72  			Header: map[string]string{
    73  				"X-GitHub-Delivery": "I am unique",
    74  				"X-Hub-Signature":   hmac,
    75  				"content-type":      "application/json",
    76  			},
    77  			Body: body,
    78  			Code: http.StatusBadRequest,
    79  		},
    80  		{
    81  			name: "No content type",
    82  
    83  			Method: http.MethodPost,
    84  			Header: map[string]string{
    85  				"X-GitHub-Event":    "ping",
    86  				"X-GitHub-Delivery": "I am unique",
    87  				"X-Hub-Signature":   hmac,
    88  			},
    89  			Body: body,
    90  			Code: http.StatusBadRequest,
    91  		},
    92  		{
    93  			name: "No event guid",
    94  
    95  			Method: http.MethodPost,
    96  			Header: map[string]string{
    97  				"X-GitHub-Event":  "ping",
    98  				"X-Hub-Signature": hmac,
    99  				"content-type":    "application/json",
   100  			},
   101  			Body: body,
   102  			Code: http.StatusBadRequest,
   103  		},
   104  		{
   105  			name: "No signature",
   106  
   107  			Method: http.MethodPost,
   108  			Header: map[string]string{
   109  				"X-GitHub-Event":    "ping",
   110  				"X-GitHub-Delivery": "I am unique",
   111  				"content-type":      "application/json",
   112  			},
   113  			Body: body,
   114  			Code: http.StatusForbidden,
   115  		},
   116  		{
   117  			name: "Bad signature",
   118  
   119  			Method: http.MethodPost,
   120  			Header: map[string]string{
   121  				"X-GitHub-Event":    "ping",
   122  				"X-GitHub-Delivery": "I am unique",
   123  				"X-Hub-Signature":   "this doesn't work",
   124  				"content-type":      "application/json",
   125  			},
   126  			Body: body,
   127  			Code: http.StatusForbidden,
   128  		},
   129  		{
   130  			name: "Good",
   131  
   132  			Method: http.MethodPost,
   133  			Header: map[string]string{
   134  				"X-GitHub-Event":    "ping",
   135  				"X-GitHub-Delivery": "I am unique",
   136  				"X-Hub-Signature":   hmac,
   137  				"content-type":      "application/json",
   138  			},
   139  			Body: body,
   140  			Code: http.StatusOK,
   141  		},
   142  		{
   143  			name: "Good, again",
   144  
   145  			Method: http.MethodGet,
   146  			Header: map[string]string{
   147  				"content-type": "application/json",
   148  			},
   149  			Body: body,
   150  			Code: http.StatusOK,
   151  		},
   152  	}
   153  
   154  	for _, tc := range testcases {
   155  		t.Logf("Running scenario %q", tc.name)
   156  
   157  		w := httptest.NewRecorder()
   158  		r, err := http.NewRequest(tc.Method, "", strings.NewReader(tc.Body))
   159  		if err != nil {
   160  			t.Fatal(err)
   161  		}
   162  		for k, v := range tc.Header {
   163  			r.Header.Set(k, v)
   164  		}
   165  		s.ServeHTTP(w, r)
   166  		if w.Code != tc.Code {
   167  			t.Errorf("For test case: %+v\nExpected code %v, got code %v", tc, tc.Code, w.Code)
   168  		}
   169  	}
   170  }
   171  
   172  func TestNeedDemux(t *testing.T) {
   173  	tests := []struct {
   174  		name string
   175  
   176  		eventType string
   177  		srcRepo   string
   178  		plugins   map[string][]plugins.ExternalPlugin
   179  
   180  		expected []plugins.ExternalPlugin
   181  	}{
   182  		{
   183  			name: "no external plugins",
   184  
   185  			eventType: "issue_comment",
   186  			srcRepo:   "kubernetes/test-infra",
   187  			plugins:   nil,
   188  
   189  			expected: nil,
   190  		},
   191  		{
   192  			name: "we have variety",
   193  
   194  			eventType: "issue_comment",
   195  			srcRepo:   "kubernetes/test-infra",
   196  			plugins: map[string][]plugins.ExternalPlugin{
   197  				"kubernetes/test-infra": {
   198  					{
   199  						Name:   "sandwich",
   200  						Events: []string{"pull_request"},
   201  					},
   202  					{
   203  						Name: "coffee",
   204  					},
   205  				},
   206  				"kubernetes/kubernetes": {
   207  					{
   208  						Name:   "gumbo",
   209  						Events: []string{"issue_comment"},
   210  					},
   211  				},
   212  				"kubernetes": {
   213  					{
   214  						Name:   "chicken",
   215  						Events: []string{"push"},
   216  					},
   217  					{
   218  						Name: "water",
   219  					},
   220  					{
   221  						Name:   "chocolate",
   222  						Events: []string{"pull_request", "issue_comment", "issues"},
   223  					},
   224  				},
   225  			},
   226  
   227  			expected: []plugins.ExternalPlugin{
   228  				{
   229  					Name: "coffee",
   230  				},
   231  				{
   232  					Name: "water",
   233  				},
   234  				{
   235  					Name:   "chocolate",
   236  					Events: []string{"pull_request", "issue_comment", "issues"},
   237  				},
   238  			},
   239  		},
   240  	}
   241  
   242  	for _, test := range tests {
   243  		t.Logf("Running scenario %q", test.name)
   244  
   245  		pa := &plugins.PluginAgent{}
   246  		pa.Set(&plugins.Configuration{
   247  			ExternalPlugins: test.plugins,
   248  		})
   249  		s := &Server{Plugins: pa}
   250  
   251  		gotPlugins := s.needDemux(test.eventType, test.srcRepo)
   252  		if len(gotPlugins) != len(test.expected) {
   253  			t.Errorf("expected plugins: %+v, got: %+v", test.expected, gotPlugins)
   254  			continue
   255  		}
   256  		for _, expected := range test.expected {
   257  			var found bool
   258  			for _, got := range gotPlugins {
   259  				if got.Name != expected.Name {
   260  					continue
   261  				}
   262  				if !reflect.DeepEqual(expected, got) {
   263  					t.Errorf("expected plugin: %+v, got: %+v", expected, got)
   264  				}
   265  				found = true
   266  			}
   267  			if !found {
   268  				t.Errorf("expected plugins: %+v, got: %+v", test.expected, gotPlugins)
   269  				break
   270  			}
   271  		}
   272  	}
   273  }