github.com/shashidharatd/test-infra@v0.0.0-20171006011030-71304e1ca560/prow/cmd/deck/main_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 main
    18  
    19  import (
    20  	"bufio"
    21  	"bytes"
    22  	"errors"
    23  	"io"
    24  	"io/ioutil"
    25  	"net/http"
    26  	"net/http/httptest"
    27  	"net/url"
    28  	"strconv"
    29  	"testing"
    30  	"time"
    31  
    32  	"github.com/ghodss/yaml"
    33  
    34  	"k8s.io/test-infra/prow/kube"
    35  )
    36  
    37  type flc int
    38  
    39  func (f flc) GetJobLog(job, id string) ([]byte, error) {
    40  	if job == "job" && id == "123" {
    41  		return []byte("hello"), nil
    42  	}
    43  	return nil, errors.New("muahaha")
    44  }
    45  
    46  func (f flc) GetJobLogStream(job, id string, options map[string]string) (io.ReadCloser, error) {
    47  	if job == "job" && id == "123" {
    48  		return ioutil.NopCloser(bytes.NewBuffer([]byte("hello\r\n"))), nil
    49  	}
    50  	return nil, errors.New("muahaha")
    51  }
    52  
    53  func TestHandleLog(t *testing.T) {
    54  	var testcases = []struct {
    55  		name string
    56  		path string
    57  		code int
    58  	}{
    59  		{
    60  			name: "no job name",
    61  			path: "",
    62  			code: http.StatusBadRequest,
    63  		},
    64  		{
    65  			name: "job but no id",
    66  			path: "?job=job",
    67  			code: http.StatusBadRequest,
    68  		},
    69  		{
    70  			name: "id but no job",
    71  			path: "?id=123",
    72  			code: http.StatusBadRequest,
    73  		},
    74  		{
    75  			name: "id and job, found",
    76  			path: "?job=job&id=123",
    77  			code: http.StatusOK,
    78  		},
    79  		{
    80  			name: "id and job, found",
    81  			path: "?job=job&id=123&follow=true",
    82  			code: http.StatusOK,
    83  		},
    84  		{
    85  			name: "id and job, not found",
    86  			path: "?job=ohno&id=123",
    87  			code: http.StatusNotFound,
    88  		},
    89  	}
    90  	handler := handleLog(flc(0))
    91  	for _, tc := range testcases {
    92  		req, err := http.NewRequest(http.MethodGet, "", nil)
    93  		if err != nil {
    94  			t.Fatalf("Error making request: %v", err)
    95  		}
    96  		u, err := url.Parse(tc.path)
    97  		if err != nil {
    98  			t.Fatalf("Error parsing URL: %v", err)
    99  		}
   100  		var follow = false
   101  		if ok, _ := strconv.ParseBool(u.Query().Get("follow")); ok {
   102  			follow = true
   103  		}
   104  		req.URL = u
   105  		rr := httptest.NewRecorder()
   106  		handler.ServeHTTP(rr, req)
   107  		if rr.Code != tc.code {
   108  			t.Errorf("Wrong error code. Got %v, want %v", rr.Code, tc.code)
   109  		} else if rr.Code == http.StatusOK {
   110  			if follow {
   111  				//wait a little to get the chunks
   112  				time.Sleep(2 * time.Millisecond)
   113  				reader := bufio.NewReader(rr.Body)
   114  				var buf bytes.Buffer
   115  				for {
   116  					line, err := reader.ReadBytes('\n')
   117  					if err == io.EOF {
   118  						break
   119  					}
   120  					if err != nil {
   121  						t.Fatalf("Expecting reply with content but got error: %v", err)
   122  					}
   123  					buf.Write(line)
   124  				}
   125  				if !bytes.Contains(buf.Bytes(), []byte("hello")) {
   126  					t.Errorf("Unexpected body: got %s.", buf.String())
   127  				}
   128  			} else {
   129  				resp := rr.Result()
   130  				defer resp.Body.Close()
   131  				if body, err := ioutil.ReadAll(resp.Body); err != nil {
   132  					t.Errorf("Error reading response body: %v", err)
   133  				} else if string(body) != "hello" {
   134  					t.Errorf("Unexpected body: got %s.", string(body))
   135  				}
   136  			}
   137  		}
   138  	}
   139  }
   140  
   141  type fpjc kube.ProwJob
   142  
   143  func (fc *fpjc) GetProwJob(name string) (kube.ProwJob, error) {
   144  	return kube.ProwJob(*fc), nil
   145  }
   146  
   147  // TestRerun just checks that the result can be unmarshaled properly, has an
   148  // updated status, and has equal spec.
   149  func TestRerun(t *testing.T) {
   150  	fc := fpjc(kube.ProwJob{
   151  		Spec: kube.ProwJobSpec{
   152  			Job: "whoa",
   153  		},
   154  		Status: kube.ProwJobStatus{
   155  			State: kube.PendingState,
   156  		},
   157  	})
   158  	handler := handleRerun(&fc)
   159  	req, err := http.NewRequest(http.MethodGet, "/rerun?prowjob=wowsuch", nil)
   160  	if err != nil {
   161  		t.Fatalf("Error making request: %v", err)
   162  	}
   163  	rr := httptest.NewRecorder()
   164  	handler.ServeHTTP(rr, req)
   165  	if rr.Code != http.StatusOK {
   166  		t.Fatalf("Bad error code: %d", rr.Code)
   167  	}
   168  	resp := rr.Result()
   169  	defer resp.Body.Close()
   170  	body, err := ioutil.ReadAll(resp.Body)
   171  	if err != nil {
   172  		t.Fatalf("Error reading response body: %v", err)
   173  	}
   174  	var res kube.ProwJob
   175  	if err := yaml.Unmarshal(body, &res); err != nil {
   176  		t.Fatalf("Error unmarshaling: %v", err)
   177  	}
   178  	if res.Spec.Job != "whoa" {
   179  		t.Errorf("Wrong job, expected \"whoa\", got \"%s\"", res.Spec.Job)
   180  	}
   181  	if res.Status.State != kube.TriggeredState {
   182  		t.Errorf("Wrong state, expected \"%v\", got \"%v\"", kube.TriggeredState, res.Status.State)
   183  	}
   184  }