forked from gleam-lang/otp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstatic_supervisor_test.gleam
142 lines (122 loc) · 4.9 KB
/
static_supervisor_test.gleam
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import gleam/erlang/process.{type Pid, type Subject}
import gleam/otp/actor
import gleam/otp/static_supervisor as sup
fn actor_child(name name, init init, loop loop) -> sup.ChildBuilder {
sup.worker_child(name, fn() {
let spec = actor.Spec(init: init, init_timeout: 10, loop: loop)
let assert Ok(subject) = actor.start_spec(spec)
Ok(process.subject_owner(subject))
})
}
// A child that sends their name back to the test process during
// initialisation so that we can tell they (re)started
fn init_notifier_child(
subject: Subject(#(String, Pid)),
name: String,
) -> sup.ChildBuilder {
actor_child(
name: name,
init: fn() {
process.send(subject, #(name, process.self()))
actor.Ready(name, process.new_selector())
},
loop: fn(_msg, state) { actor.continue(state) },
)
}
pub fn one_for_one_test() {
let subject = process.new_subject()
let assert Ok(supervisor) =
sup.new(sup.OneForOne)
|> sup.add(init_notifier_child(subject, "1"))
|> sup.add(init_notifier_child(subject, "2"))
|> sup.add(init_notifier_child(subject, "3"))
|> sup.start_link
// Assert children have started
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Ok(#("3", p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
// Shutdown first child and assert only it restarts
process.kill(p1)
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
// Shutdown second child and assert only it restarts
process.kill(p2)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
let assert True = process.is_alive(supervisor)
process.send_exit(supervisor)
}
pub fn rest_for_one_test() {
let subject = process.new_subject()
let assert Ok(supervisor) =
sup.new(sup.RestForOne)
|> sup.add(init_notifier_child(subject, "1"))
|> sup.add(init_notifier_child(subject, "2"))
|> sup.add(init_notifier_child(subject, "3"))
|> sup.start_link
// Assert children have started
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", _p2)) = process.receive(subject, 10)
let assert Ok(#("3", _p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
// Shutdown first child and assert all restart
process.kill(p1)
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Ok(#("3", p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
// Shutdown second child and following restart
process.kill(p2)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Ok(#("3", p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
let assert True = process.is_alive(supervisor)
process.send_exit(supervisor)
}
pub fn one_for_all_test() {
let subject = process.new_subject()
let assert Ok(supervisor) =
sup.new(sup.OneForAll)
|> sup.add(init_notifier_child(subject, "1"))
|> sup.add(init_notifier_child(subject, "2"))
|> sup.add(init_notifier_child(subject, "3"))
|> sup.start_link
// Assert children have started
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", _p2)) = process.receive(subject, 10)
let assert Ok(#("3", _p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
// Shutdown first child and all restart
process.kill(p1)
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Ok(#("3", p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
// Shutdown second child and all restart
process.kill(p2)
let assert Ok(#("1", p1)) = process.receive(subject, 10)
let assert Ok(#("2", p2)) = process.receive(subject, 10)
let assert Ok(#("3", p3)) = process.receive(subject, 10)
let assert Error(Nil) = process.receive(subject, 10)
let assert True = process.is_alive(p1)
let assert True = process.is_alive(p2)
let assert True = process.is_alive(p3)
let assert True = process.is_alive(supervisor)
process.send_exit(supervisor)
}