github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/prow/tide/search_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 tide
    18  
    19  import (
    20  	"testing"
    21  	"time"
    22  
    23  	githubql "github.com/shurcooL/githubv4"
    24  
    25  	"k8s.io/apimachinery/pkg/util/sets"
    26  	"k8s.io/test-infra/prow/github"
    27  )
    28  
    29  func uniformRangeAgeFunc(start, end time.Time, count int) func(int) time.Time {
    30  	diff := end.Sub(start)
    31  	step := diff / time.Duration(count)
    32  	return func(prNum int) time.Time {
    33  		return start.Add(step * time.Duration(prNum))
    34  	}
    35  }
    36  
    37  func testSearchExecutor(ageFunc func(int) time.Time, count int) searchExecutor {
    38  	prs := make(map[time.Time]PullRequest, count)
    39  	for i := 0; i < count; i++ {
    40  		prs[ageFunc(i)] = PullRequest{Number: githubql.Int(i)}
    41  	}
    42  	return func(start, end time.Time) ([]PullRequest, int, error) {
    43  		var res []PullRequest
    44  		for t, pr := range prs {
    45  			if t.Before(start) || t.After(end) {
    46  				continue
    47  			}
    48  			res = append(res, pr)
    49  		}
    50  		return res, len(res), nil
    51  	}
    52  }
    53  
    54  func TestSearch(t *testing.T) {
    55  	month := time.Hour * time.Duration(24*30)
    56  
    57  	now := time.Now()
    58  	recent := now.Add(-month)
    59  	old := now.Add(-month * time.Duration(24))
    60  	ancient := github.FoundingYear.Add(month * time.Duration(12))
    61  
    62  	// For each test case, create 'count' PRs using 'ageFunc' to define their
    63  	// distribution over time. Validate that all 'count' PRs are found.
    64  	tcs := []struct {
    65  		name    string
    66  		ageFunc func(prNum int) time.Time
    67  		count   int
    68  	}{
    69  		{
    70  			name:    "less than 1000, recent->now",
    71  			ageFunc: uniformRangeAgeFunc(recent, now, 900),
    72  			count:   900,
    73  		},
    74  		{
    75  			name:    "exactly 1000, old->now",
    76  			ageFunc: uniformRangeAgeFunc(old, now, 1000),
    77  			count:   1000,
    78  		},
    79  		{
    80  			name:    "1500, recent->now",
    81  			ageFunc: uniformRangeAgeFunc(recent, now, 1500),
    82  			count:   1500,
    83  		},
    84  		{
    85  			name:    "3500, recent->now",
    86  			ageFunc: uniformRangeAgeFunc(recent, now, 3500),
    87  			count:   3500,
    88  		},
    89  		{
    90  			name:    "1500, ancient->now",
    91  			ageFunc: uniformRangeAgeFunc(ancient, now, 1500),
    92  			count:   1500,
    93  		},
    94  		{
    95  			name:    "3500, ancient->now",
    96  			ageFunc: uniformRangeAgeFunc(ancient, now, 3500),
    97  			count:   3500,
    98  		},
    99  		{
   100  			name:    "1500, ancient->old",
   101  			ageFunc: uniformRangeAgeFunc(ancient, old, 1500),
   102  			count:   1500,
   103  		},
   104  		{
   105  			name:    "3500, ancient->old",
   106  			ageFunc: uniformRangeAgeFunc(ancient, old, 3500),
   107  			count:   3500,
   108  		},
   109  		{
   110  			name:    "7000, old->now",
   111  			ageFunc: uniformRangeAgeFunc(old, now, 7000),
   112  			count:   7000,
   113  		},
   114  		{
   115  			name:  "0 PRs",
   116  			count: 0,
   117  		},
   118  	}
   119  
   120  	for _, tc := range tcs {
   121  		prs, err := testSearchExecutor(tc.ageFunc, tc.count).search()
   122  		if err != nil {
   123  			t.Fatalf("Unexpected error: %v.", err)
   124  		}
   125  
   126  		// Validate that there are 'tc.count' unique PRs in 'prs'.
   127  		found := sets.NewInt()
   128  		for _, pr := range prs {
   129  			if found.Has(int(pr.Number)) {
   130  				t.Errorf("Found PR #%d multiple times.", int(pr.Number))
   131  			}
   132  			found.Insert(int(pr.Number))
   133  		}
   134  		if found.Len() != tc.count {
   135  			t.Errorf("Expected to find %d PRs, but found %d instead.", tc.count, found.Len())
   136  		}
   137  	}
   138  }