github.com/yanishoss/schedulo@v1.2.2/internal/core/stack_manager_test.go (about) 1 package core 2 3 import ( 4 "math/rand" 5 "testing" 6 "time" 7 ) 8 9 var config = StackManagerConfig{ 10 StacksNumber: 20000, 11 DefaultStackCapacity: 50, 12 MaxStackCapacity: 100, 13 } 14 15 var ev = generateEvents(2 * config.StacksNumber * config.DefaultStackCapacity) 16 17 func TestStackManager(t *testing.T) { 18 var config = StackManagerConfig{ 19 StacksNumber: 5, 20 DefaultStackCapacity: 300, 21 } 22 23 s := newStackManager(config) 24 25 if len(s.stacks) != config.StacksNumber { 26 t.Fatalf("The stack manager doesn't have enough stacks: expect %d, got %d\n", config.StacksNumber, s.stacks.Len()) 27 } 28 29 if s.stacks[0].cap < config.DefaultStackCapacity { 30 t.Fatalf("The stack manager doesn't have enough stack capacity: expect %d, got %d\n", config.DefaultStackCapacity, s.stacks[0].len) 31 } 32 33 ev := generateEvents(config.DefaultStackCapacity*config.StacksNumber + 10) 34 35 for i, e := range ev { 36 if i == config.DefaultStackCapacity*config.StacksNumber-1 { 37 break 38 } 39 40 _ = s.Push(e) 41 } 42 43 for i := 0; i < s.stacks[0].len; i++ { 44 ev := s.stacks[0].Get(i) 45 46 if i-1 >= 0 { 47 evBefore := s.stacks[0].Get(i - 1) 48 49 if ev.ShouldExecuteAt.Before(evBefore.ShouldExecuteAt) { 50 t.Fatalf("The stack must be sorted timestamp ascending wise\n") 51 } 52 } 53 54 if i+1 <= s.stacks[0].len-1 { 55 evAfter := s.stacks[0].Get(i + 1) 56 57 if ev.ShouldExecuteAt.After(evAfter.ShouldExecuteAt) { 58 t.Fatalf("The stack must be sorted timestamp ascending wise\n") 59 } 60 } 61 } 62 63 for i, e := range ev[config.DefaultStackCapacity*config.StacksNumber-1:] { 64 if i == config.DefaultStackCapacity*config.StacksNumber-1 { 65 break 66 } 67 68 _ = s.Push(e) 69 } 70 71 if s.stacks[0].cap <= config.DefaultStackCapacity { 72 t.Fatalf("The stack capacity must be expanded as new events have been pushed: %d capacity\n", s.stacks[0].cap) 73 } 74 75 if err := s.resize(7); err != nil { 76 t.Error(err) 77 } 78 79 if len(s.stacks) != 7 { 80 t.Fatalf("The number of stack must be resized: expect:%d, got:%d\n", 7, len(s.stacks)) 81 } 82 83 oldLen := s.Len() 84 85 if err := s.resize(2); err != nil { 86 t.Error(err) 87 } 88 89 if s.stacks.Len() != 2 { 90 t.Fatalf("The stack manager has not been resized: expected:%d, got:%d", 2, s.stacks.Len()) 91 } 92 93 if s.Len() != oldLen { 94 t.Fatalf("Elements have been lost while resizing the stack manager: expected:%d, got:%d\n", oldLen, s.Len()) 95 } 96 97 ev = generateEvents(2*maxDefaultStackCapacity - len(ev) + 1) 98 99 var err1 error 100 for _, e := range ev { 101 err := s.Push(e) 102 103 if err != nil { 104 err1 = err 105 } 106 } 107 108 if err1 == nil { 109 t.Fatalf("Max capacity has been reached but no error was raised\n") 110 } else { 111 t.Logf("This error code is normal: %s\n", err1.Error()) 112 } 113 114 if err := s.resize(1); err == nil { 115 t.Fatalf("Max capacity has already been reached but no error was raised\n") 116 } 117 } 118 119 func BenchmarkInsertingBelowCapacity(b *testing.B) { 120 b.StopTimer() 121 s := newStackManager(config) 122 123 smpl := ev[:config.DefaultStackCapacity*config.StacksNumber] 124 125 b.StartTimer() 126 for _, e := range smpl { 127 err := s.Push(e) 128 129 if err != nil { 130 b.Error(err) 131 } 132 } 133 } 134 135 func BenchmarkInsertingPastCapacity(b *testing.B) { 136 b.StopTimer() 137 s := newStackManager(config) 138 139 smpl := ev[:config.StacksNumber*config.DefaultStackCapacity-1] 140 141 for _, e := range smpl { 142 err := s.Push(e) 143 144 if err != nil { 145 b.Error(err) 146 } 147 } 148 149 smpl2 := ev[config.StacksNumber*config.DefaultStackCapacity:] 150 151 b.StartTimer() 152 for _, e := range smpl2 { 153 err := s.Push(e) 154 155 if err != nil { 156 b.Error(err) 157 } 158 } 159 } 160 161 func randomID(n int) ID { 162 const CHARACTERS = "AZERTYUIOPQSDFGHJKLMWXCVBN1234567890" 163 164 str := "" 165 166 for i := 0; i < n; i++ { 167 j := rand.Intn(len(CHARACTERS) - 1) 168 169 str += string(CHARACTERS[j]) 170 } 171 172 return ID(str) 173 } 174 175 func generateEvents(n int) []event { 176 const idSize = 8 177 178 ev := make([]event, n) 179 180 for i := 0; i < n; i++ { 181 ev[i] = event{ 182 Mode: TimestampMode, 183 ShouldExecuteAt: time.Now().Add(time.Duration(time.Second.Nanoseconds() * int64(i+1))), 184 ID: randomID(idSize), 185 } 186 } 187 188 return ev 189 }