-
Notifications
You must be signed in to change notification settings - Fork 179
Expand file tree
/
Copy pathprocess_test.go
More file actions
140 lines (124 loc) · 3.1 KB
/
Copy pathprocess_test.go
File metadata and controls
140 lines (124 loc) · 3.1 KB
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
package actor
import (
"bytes"
"fmt"
"testing"
"time"
"github.com/stretchr/testify/require"
)
type triggerPanic struct {
data int
}
func Test_ProcessingStartsFromNextMessageAfterRestart(t *testing.T) {
e, err := NewEngine(NewEngineConfig())
require.NoError(t, err)
done := make(chan struct{})
pid := e.SpawnFunc(func(c *Context) {
fmt.Printf("Got message type %T\n", c.Message())
if _, ok := c.Message().(triggerPanic); ok {
// message causing the failure is not processed again.
panicWrapper()
}
if s, ok := c.Message().(string); ok && s == "foo" {
close(done)
}
}, "kind", WithMaxRestarts(1))
e.Send(pid, triggerPanic{})
e.Send(pid, "foo")
<-done
}
// Test_CleanTrace tests that the stack trace is cleaned up correctly and that the function
// which triggers the panic is at the top of the stack trace.
func Test_CleanTrace(t *testing.T) {
e, err := NewEngine(NewEngineConfig())
require.NoError(t, err)
stopCh := make(chan struct{})
pid := e.SpawnFunc(func(c *Context) {
fmt.Printf("Got message type %T\n", c.Message())
switch c.Message().(type) {
case Started:
c.Engine().Subscribe(c.pid)
case triggerPanic:
panicWrapper()
case ActorRestartedEvent:
m := c.Message().(ActorRestartedEvent)
// split the panic into lines:
lines := bytes.Split(m.Stacktrace, []byte("\n"))
// check that the second line is the panicWrapper function:
if bytes.Contains(lines[1], []byte("panicWrapper")) {
fmt.Println("stack trace contains panicWrapper at the right line")
stopCh <- struct{}{}
}
}
}, "foo", WithMaxRestarts(1))
e.Send(pid, triggerPanic{1})
select {
case <-stopCh:
fmt.Println("test passed")
case <-time.After(time.Second):
t.Error("test timed out. stack trace likely did not contain panicWrapper at the right line")
}
}
func panicWrapper() {
panic("foo")
}
func Test_StartupMessages(t *testing.T) {
e, err := NewEngine(NewEngineConfig())
require.NoError(t, err)
type testMsg struct{}
timeout := time.After(1 * time.Second)
msgCh := make(chan any, 10) // used to check the msg order
syncCh1 := make(chan struct{})
syncCh2 := make(chan struct{})
go func() {
e.SpawnFunc(func(c *Context) {
fmt.Printf("Got message type %T\n", c.Message())
switch c.Message().(type) {
case Initialized:
syncCh1 <- struct{}{}
// wait for testMsg to send
select {
case <-syncCh2:
case <-timeout:
t.Error("test timed out")
}
}
msgCh <- c.Message()
}, "foo", WithID("bar"))
}()
// wait for actor to initialize
select {
case <-syncCh1:
case <-timeout:
t.Error("test timed out")
return
}
pid := e.Registry.GetPID("foo", "bar")
e.Send(pid, testMsg{})
syncCh2 <- struct{}{}
// check that message order is as expected
select {
case msg := <-msgCh:
_, ok := msg.(Initialized)
require.True(t, ok)
case <-timeout:
t.Error("test timed out")
return
}
select {
case msg := <-msgCh:
_, ok := msg.(Started)
require.True(t, ok)
case <-timeout:
t.Error("test timed out")
return
}
select {
case msg := <-msgCh:
_, ok := msg.(testMsg)
require.True(t, ok)
case <-timeout:
t.Error("test timed out")
return
}
}