github.com/bigcommerce/nomad@v0.9.3-bc/nomad/timetable_test.go (about)

     1  package nomad
     2  
     3  import (
     4  	"bytes"
     5  	"sync"
     6  	"testing"
     7  	"time"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"github.com/google/go-cmp/cmp/cmpopts"
    11  	"github.com/hashicorp/nomad/nomad/structs"
    12  	"github.com/ugorji/go/codec"
    13  )
    14  
    15  func TestTimeTable(t *testing.T) {
    16  	t.Parallel()
    17  	tt := NewTimeTable(time.Second, time.Minute)
    18  
    19  	index := tt.NearestIndex(time.Now())
    20  	if index != 0 {
    21  		t.Fatalf("bad: %v", index)
    22  	}
    23  
    24  	when := tt.NearestTime(1000)
    25  	if !when.IsZero() {
    26  		t.Fatalf("bad: %v", when)
    27  	}
    28  
    29  	// Witness some data
    30  	start := time.Now()
    31  	plusOne := start.Add(time.Minute)
    32  	plusTwo := start.Add(2 * time.Minute)
    33  	plusFive := start.Add(5 * time.Minute)
    34  	plusThirty := start.Add(30 * time.Minute)
    35  	plusHour := start.Add(60 * time.Minute)
    36  	plusHourHalf := start.Add(90 * time.Minute)
    37  
    38  	tt.Witness(2, start)
    39  	tt.Witness(2, start)
    40  
    41  	tt.Witness(10, plusOne)
    42  	tt.Witness(10, plusOne)
    43  
    44  	tt.Witness(20, plusTwo)
    45  	tt.Witness(20, plusTwo)
    46  
    47  	tt.Witness(30, plusFive)
    48  	tt.Witness(30, plusFive)
    49  
    50  	tt.Witness(40, plusThirty)
    51  	tt.Witness(40, plusThirty)
    52  
    53  	tt.Witness(50, plusHour)
    54  	tt.Witness(50, plusHour)
    55  
    56  	type tcase struct {
    57  		when        time.Time
    58  		expectIndex uint64
    59  
    60  		index      uint64
    61  		expectWhen time.Time
    62  	}
    63  	cases := []tcase{
    64  		// Exact match
    65  		{start, 2, 2, start},
    66  		{plusOne, 10, 10, plusOne},
    67  		{plusHour, 50, 50, plusHour},
    68  
    69  		// Before the newest entry
    70  		{plusHourHalf, 50, 51, plusHour},
    71  
    72  		// After the oldest entry
    73  		{time.Time{}, 0, 1, time.Time{}},
    74  
    75  		// Mid range
    76  		{start.Add(3 * time.Minute), 20, 25, plusTwo},
    77  	}
    78  
    79  	for _, tc := range cases {
    80  		index := tt.NearestIndex(tc.when)
    81  		if index != tc.expectIndex {
    82  			t.Fatalf("bad: %v %v", index, tc.expectIndex)
    83  		}
    84  
    85  		when := tt.NearestTime(tc.index)
    86  		if when != tc.expectWhen {
    87  			t.Fatalf("bad: for %d %v %v", tc.index, when, tc.expectWhen)
    88  		}
    89  	}
    90  }
    91  
    92  func TestTimeTable_SerializeDeserialize(t *testing.T) {
    93  	t.Parallel()
    94  	tt := NewTimeTable(time.Second, time.Minute)
    95  
    96  	// Witness some data
    97  	start := time.Now()
    98  	plusOne := start.Add(time.Minute)
    99  	plusTwo := start.Add(2 * time.Minute)
   100  	plusFive := start.Add(5 * time.Minute)
   101  	plusThirty := start.Add(30 * time.Minute)
   102  	plusHour := start.Add(60 * time.Minute)
   103  
   104  	tt.Witness(2, start)
   105  	tt.Witness(10, plusOne)
   106  	tt.Witness(20, plusTwo)
   107  	tt.Witness(30, plusFive)
   108  	tt.Witness(40, plusThirty)
   109  	tt.Witness(50, plusHour)
   110  
   111  	var buf bytes.Buffer
   112  	enc := codec.NewEncoder(&buf, structs.MsgpackHandle)
   113  
   114  	err := tt.Serialize(enc)
   115  	if err != nil {
   116  		t.Fatalf("err: %v", err)
   117  	}
   118  
   119  	dec := codec.NewDecoder(&buf, structs.MsgpackHandle)
   120  
   121  	tt2 := NewTimeTable(time.Second, time.Minute)
   122  	err = tt2.Deserialize(dec)
   123  	if err != nil {
   124  		t.Fatalf("err: %v", err)
   125  	}
   126  
   127  	o := cmp.AllowUnexported(TimeTable{})
   128  	o2 := cmpopts.IgnoreTypes(sync.RWMutex{})
   129  	if !cmp.Equal(tt.table, tt2.table, o, o2) {
   130  		t.Fatalf("bad: %s", cmp.Diff(tt, tt2, o, o2))
   131  	}
   132  }
   133  
   134  func TestTimeTable_Overflow(t *testing.T) {
   135  	t.Parallel()
   136  	tt := NewTimeTable(time.Second, 3*time.Second)
   137  
   138  	// Witness some data
   139  	start := time.Now()
   140  	plusOne := start.Add(time.Second)
   141  	plusTwo := start.Add(2 * time.Second)
   142  	plusThree := start.Add(3 * time.Second)
   143  
   144  	tt.Witness(10, start)
   145  	tt.Witness(20, plusOne)
   146  	tt.Witness(30, plusTwo)
   147  	tt.Witness(40, plusThree)
   148  
   149  	if len(tt.table) != 3 {
   150  		t.Fatalf("bad")
   151  	}
   152  
   153  	index := tt.NearestIndex(start)
   154  	if index != 0 {
   155  		t.Fatalf("bad: %v %v", index, 0)
   156  	}
   157  
   158  	when := tt.NearestTime(15)
   159  	if !when.IsZero() {
   160  		t.Fatalf("bad: %v", when)
   161  	}
   162  }