github.com/ergo-services/ergo@v1.999.224/tests/supervisor_sofo_test.go (about) 1 package tests 2 3 // - Supervisor 4 5 // - simple one for one (permanent) 6 // start node1 7 // start supevisor sv1 with genservers gs1,gs2,gs3 8 // .... TODO: describe 9 10 import ( 11 "fmt" 12 "testing" 13 14 "github.com/ergo-services/ergo" 15 "github.com/ergo-services/ergo/etf" 16 "github.com/ergo-services/ergo/gen" 17 "github.com/ergo-services/ergo/node" 18 ) 19 20 type testSupervisorSimpleOneForOne struct { 21 gen.Supervisor 22 ch chan interface{} 23 } 24 25 func TestSupervisorSimpleOneForOne(t *testing.T) { 26 fmt.Printf("\n=== Test Supervisor - simple one for one\n") 27 fmt.Printf("Starting node nodeSvSimpleOneForOne@localhost: ") 28 node1, _ := ergo.StartNode("nodeSvSimpleOneForOne@localhost", "cookies", node.Options{}) 29 if node1 == nil { 30 t.Fatal("can't start node") 31 } else { 32 fmt.Println("OK") 33 } 34 sv := &testSupervisorSimpleOneForOne{ 35 ch: make(chan interface{}, 10), 36 } 37 38 // =================================================================================================== 39 // test SupervisorStrategyRestartPermanent 40 testCases := []ChildrenTestCase{ 41 { 42 reason: "abnormal", 43 statuses: []string{"new", "new", "new", "new", "new", "new"}, 44 events: 12, // waiting for 6 terminates and 6 restarts 45 }, 46 { 47 reason: "normal", 48 statuses: []string{"new", "new", "new", "new", "new", "new"}, 49 events: 12, // waiting for 6 terminates and 6 restarts 50 }, 51 { 52 reason: "shutdown", 53 statuses: []string{"new", "new", "new", "new", "new", "new"}, 54 events: 12, // waiting for 6 terminates and 6 restarts 55 }, 56 } 57 58 for c := range testCases { 59 fmt.Printf("Starting supervisor 'testSupervisorPermanent' (%s)... ", gen.SupervisorStrategyRestartPermanent) 60 processSV, err := node1.Spawn("testSupervisorPermanent", gen.ProcessOptions{}, sv, gen.SupervisorStrategyRestartPermanent) 61 if err != nil { 62 t.Fatal(err) 63 } 64 65 children := make([]etf.Pid, 6) 66 // starting supervisor shouldn't cause start its children 67 children1, err := waitNeventsSupervisorChildren(sv.ch, 0, children) 68 if err != nil { 69 t.Fatal(err) 70 } else { 71 // must be equal 72 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 73 if checkExpectedChildrenStatus(children, children1, statuses) { 74 fmt.Println("OK") 75 children = children1 76 } else { 77 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 78 t.Fatal(e) 79 } 80 } 81 fmt.Printf("... starting 6 children ... ") 82 83 // start children 84 for i := 0; i < 6; i = i + 2 { 85 p, e := sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i) 86 if e != nil { 87 t.Fatal(e) 88 } 89 children[i] = p.Self() 90 // start twice. must be able to start any number of child processes 91 // as it doesn't register this process with the given name. 92 p, e = sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i+1) 93 if e != nil { 94 t.Fatal(e) 95 } 96 children[i+1] = p.Self() 97 } 98 if children1, err := waitNeventsSupervisorChildren(sv.ch, 6, children); err != nil { 99 t.Fatal(err) 100 } else { 101 // they should be equal after start 102 statuses := []string{"old", "old", "old", "old", "old", "old"} 103 if checkExpectedChildrenStatus(children, children1, statuses) { 104 fmt.Println("OK") 105 } else { 106 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 107 t.Fatal(e) 108 } 109 } 110 111 // kill them all with reason = testCases[c].reason 112 fmt.Printf("... stopping children with '%s' reason and waiting for restarting all of them ... ", testCases[c].reason) 113 114 for k := range children { 115 processSV.Send(children[k], testCases[c].reason) 116 } 117 118 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events, children); err != nil { 119 t.Fatal(err) 120 } else { 121 if checkExpectedChildrenStatus(children, children1, testCases[c].statuses) { 122 fmt.Println("OK") 123 children = children1 124 } else { 125 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", testCases[c].statuses, children, children1) 126 t.Fatal(e) 127 } 128 } 129 130 fmt.Printf("Stopping supervisor 'testSupervisor' (reason: %s)... ", testCases[c].reason) 131 processSV.Exit(testCases[c].reason) 132 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events-len(children), children); err != nil { 133 t.Fatal(err) 134 } else { 135 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 136 if checkExpectedChildrenStatus(children, children1, statuses) { 137 fmt.Println("OK") 138 } else { 139 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 140 t.Fatal(e) 141 } 142 } 143 144 } 145 146 // =================================================================================================== 147 // test SupervisorStrategyRestartTransient 148 testCases = []ChildrenTestCase{ 149 { 150 reason: "abnormal", 151 statuses: []string{"new", "new", "new", "new", "new", "new"}, 152 events: 12, // waiting for 6 terminates and 6 restarts 153 }, 154 { 155 reason: "normal", 156 statuses: []string{"empty", "empty", "empty", "empty", "empty", "empty"}, 157 events: 6, // waiting for 6 terminates 158 }, 159 { 160 reason: "shutdown", 161 statuses: []string{"empty", "empty", "empty", "empty", "empty", "empty"}, 162 events: 6, // waiting for 6 terminates 163 }, 164 } 165 166 for c := range testCases { 167 fmt.Printf("Starting supervisor 'testSupervisorTransient' (%s)... ", gen.SupervisorStrategyRestartTransient) 168 processSV, err := node1.Spawn("testSupervisorTransient", gen.ProcessOptions{}, sv, gen.SupervisorStrategyRestartTransient) 169 if err != nil { 170 t.Fatal(err) 171 } 172 173 children := make([]etf.Pid, 6) 174 // starting supervisor shouldn't cause start its children 175 children1, err := waitNeventsSupervisorChildren(sv.ch, 0, children) 176 if err != nil { 177 t.Fatal(err) 178 } else { 179 // must be equal 180 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 181 if checkExpectedChildrenStatus(children, children1, statuses) { 182 fmt.Println("OK") 183 children = children1 184 } else { 185 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 186 t.Fatal(e) 187 } 188 } 189 fmt.Printf("... starting 6 children ... ") 190 191 // start children 192 for i := 0; i < 6; i = i + 2 { 193 p, e := sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i) 194 if e != nil { 195 t.Fatal(e) 196 } 197 children[i] = p.Self() 198 // start twice. must be able to start any number of child processes 199 // as it doesn't register this process with the given name. 200 p, e = sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i+1) 201 if e != nil { 202 t.Fatal(e) 203 } 204 children[i+1] = p.Self() 205 } 206 if children1, err := waitNeventsSupervisorChildren(sv.ch, 6, children); err != nil { 207 t.Fatal(err) 208 } else { 209 // they should be equal after start 210 statuses := []string{"old", "old", "old", "old", "old", "old"} 211 if checkExpectedChildrenStatus(children, children1, statuses) { 212 fmt.Println("OK") 213 } else { 214 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 215 t.Fatal(e) 216 } 217 } 218 219 // kill them all with reason = testCases[c].reason 220 fmt.Printf("... stopping children with '%s' reason and waiting for restarting some of them ... ", testCases[c].reason) 221 222 for k := range children { 223 processSV.Send(children[k], testCases[c].reason) 224 } 225 226 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events, children); err != nil { 227 t.Fatal(err) 228 } else { 229 if checkExpectedChildrenStatus(children, children1, testCases[c].statuses) { 230 fmt.Println("OK") 231 children = children1 232 } else { 233 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", testCases[c].statuses, children, children1) 234 t.Fatal(e) 235 } 236 } 237 238 fmt.Printf("Stopping supervisor 'testSupervisor' (reason: %s)... ", testCases[c].reason) 239 processSV.Exit(testCases[c].reason) 240 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events-len(children), children); err != nil { 241 t.Fatal(err) 242 } else { 243 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 244 if checkExpectedChildrenStatus(children, children1, statuses) { 245 fmt.Println("OK") 246 } else { 247 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 248 t.Fatal(e) 249 } 250 } 251 252 } 253 254 // =================================================================================================== 255 // test SupervisorStrategyRestartTemporary 256 testCases = []ChildrenTestCase{ 257 { 258 reason: "abnormal", 259 statuses: []string{"empty", "empty", "empty", "empty", "empty", "empty"}, 260 events: 6, // waiting for 6 terminates 261 }, 262 { 263 reason: "normal", 264 statuses: []string{"empty", "empty", "empty", "empty", "empty", "empty"}, 265 events: 6, // waiting for 6 terminates 266 }, 267 { 268 reason: "shutdown", 269 statuses: []string{"empty", "empty", "empty", "empty", "empty", "empty"}, 270 events: 6, // waiting for 6 terminates 271 }, 272 } 273 274 for c := range testCases { 275 fmt.Printf("Starting supervisor 'testSupervisorTemporary' (%s)... ", gen.SupervisorStrategyRestartTemporary) 276 processSV, err := node1.Spawn("testSupervisorTemporary", gen.ProcessOptions{}, sv, gen.SupervisorStrategyRestartTemporary) 277 if err != nil { 278 t.Fatal(err) 279 } 280 281 children := make([]etf.Pid, 6) 282 // starting supervisor shouldn't cause start its children 283 children1, err := waitNeventsSupervisorChildren(sv.ch, 0, children) 284 if err != nil { 285 t.Fatal(err) 286 } else { 287 // must be equal 288 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 289 if checkExpectedChildrenStatus(children, children1, statuses) { 290 fmt.Println("OK") 291 children = children1 292 } else { 293 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 294 t.Fatal(e) 295 } 296 } 297 fmt.Printf("... starting 6 children ... ") 298 299 // start children 300 for i := 0; i < 6; i = i + 2 { 301 p, e := sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i) 302 if e != nil { 303 t.Fatal(e) 304 } 305 children[i] = p.Self() 306 // start twice. must be able to start any number of child processes 307 // as it doesn't register this process with the given name. 308 p, e = sv.StartChild(processSV, fmt.Sprintf("testGS%d", i/2+1), sv.ch, i+1) 309 if e != nil { 310 t.Fatal(e) 311 } 312 children[i+1] = p.Self() 313 } 314 if children1, err := waitNeventsSupervisorChildren(sv.ch, 6, children); err != nil { 315 t.Fatal(err) 316 } else { 317 // they should be equal after start 318 statuses := []string{"old", "old", "old", "old", "old", "old"} 319 if checkExpectedChildrenStatus(children, children1, statuses) { 320 fmt.Println("OK") 321 } else { 322 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 323 t.Fatal(e) 324 } 325 } 326 327 // kill them all with reason = testCases[c].reason 328 fmt.Printf("... stopping children with '%s' reason and waiting for exiting all of them ... ", testCases[c].reason) 329 330 for k := range children { 331 processSV.Send(children[k], testCases[c].reason) 332 } 333 334 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events, children); err != nil { 335 t.Fatal(err) 336 } else { 337 if checkExpectedChildrenStatus(children, children1, testCases[c].statuses) { 338 fmt.Println("OK") 339 children = children1 340 } else { 341 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", testCases[c].statuses, children, children1) 342 t.Fatal(e) 343 } 344 } 345 346 fmt.Printf("Stopping supervisor 'testSupervisor' (reason: %s)... ", testCases[c].reason) 347 processSV.Exit(testCases[c].reason) 348 if children1, err := waitNeventsSupervisorChildren(sv.ch, testCases[c].events-len(children), children); err != nil { 349 t.Fatal(err) 350 } else { 351 statuses := []string{"empty", "empty", "empty", "empty", "empty", "empty"} 352 if checkExpectedChildrenStatus(children, children1, statuses) { 353 fmt.Println("OK") 354 } else { 355 e := fmt.Errorf("got something else except we expected (%v). old: %v new: %v", statuses, children, children1) 356 t.Fatal(e) 357 } 358 } 359 360 } 361 } 362 363 func (ts *testSupervisorSimpleOneForOne) Init(args ...etf.Term) (gen.SupervisorSpec, error) { 364 restart := args[0].(string) 365 return gen.SupervisorSpec{ 366 Children: []gen.SupervisorChildSpec{ 367 { 368 Name: "testGS1", 369 Child: &testSupervisorGenServer{}, 370 }, 371 { 372 Name: "testGS2", 373 Child: &testSupervisorGenServer{}, 374 }, 375 { 376 Name: "testGS3", 377 Child: &testSupervisorGenServer{}, 378 }, 379 }, 380 Strategy: gen.SupervisorStrategy{ 381 Type: gen.SupervisorStrategySimpleOneForOne, 382 Intensity: 10, 383 Period: 5, 384 Restart: restart, 385 }, 386 }, nil 387 }