1package phony
2
3import (
4	"testing"
5	"unsafe"
6)
7
8func TestInboxSize(t *testing.T) {
9	var a Inbox
10	var q queueElem
11	t.Logf("Inbox size: %d, message size: %d", unsafe.Sizeof(a), unsafe.Sizeof(q))
12}
13
14func TestBlock(t *testing.T) {
15	var a Inbox
16	var results []int
17	for idx := 0; idx < 1024; idx++ {
18		n := idx // Because idx gets mutated in place
19		Block(&a, func() {
20			results = append(results, n)
21		})
22	}
23	for idx, n := range results {
24		if n != idx {
25			t.Errorf("value %d != index %d", n, idx)
26		}
27	}
28}
29
30func TestAct(t *testing.T) {
31	var a Inbox
32	var results []int
33	Block(&a, func() {
34		for idx := 0; idx < 1024; idx++ {
35			n := idx // Because idx gets mutated in place
36			a.Act(&a, func() {
37				results = append(results, n)
38			})
39		}
40	})
41	Block(&a, func() {})
42	for idx, n := range results {
43		if n != idx {
44			t.Errorf("value %d != index %d", n, idx)
45		}
46	}
47}
48
49func TestPanicAct(t *testing.T) {
50	defer func() {
51		if r := recover(); r == nil {
52			t.Errorf("The code did not panic")
53		}
54	}()
55	var a Inbox
56	a.Act(nil, nil)
57}
58
59func TestPanicBlockActor(t *testing.T) {
60	defer func() {
61		if r := recover(); r == nil {
62			t.Errorf("The code did not panic")
63		}
64	}()
65	Block(nil, nil)
66}
67
68func TestPanicBlockAction(t *testing.T) {
69	defer func() {
70		if r := recover(); r == nil {
71			t.Errorf("The code did not panic")
72		}
73	}()
74	var a Inbox
75	Block(&a, nil)
76}
77
78func BenchmarkLoopActor(b *testing.B) {
79	var a Inbox
80	done := make(chan struct{})
81	idx := 0
82	var f func()
83	f = func() {
84		if idx < b.N {
85			idx++
86			a.Act(nil, f)
87		} else {
88			close(done)
89		}
90	}
91	a.Act(nil, f)
92	<-done
93}
94
95func BenchmarkLoopChannel(b *testing.B) {
96	ch := make(chan func(), 1)
97	defer close(ch)
98	go func() {
99		for f := range ch {
100			f()
101		}
102	}()
103	done := make(chan struct{})
104	idx := 0
105	var f func()
106	f = func() {
107		if idx < b.N {
108			idx++
109			ch <- f
110		} else {
111			close(done)
112		}
113	}
114	ch <- f
115	<-done
116}
117
118func BenchmarkSendActor(b *testing.B) {
119	var a, s Inbox
120	done := make(chan struct{})
121	idx := 0
122	var f func()
123	f = func() {
124		if idx < b.N {
125			idx++
126			a.Act(&s, func() {})
127			s.Act(nil, f)
128		} else {
129			a.Act(&s, func() { close(done) })
130		}
131	}
132	s.Act(nil, f)
133	<-done
134}
135
136func BenchmarkSendChannel(b *testing.B) {
137	done := make(chan struct{})
138	ch := make(chan func())
139	go func() {
140		for f := range ch {
141			f()
142		}
143		close(done)
144	}()
145	f := func() {}
146	for i := 0; i < b.N; i++ {
147		ch <- f
148	}
149	close(ch)
150	<-done
151}
152
153func BenchmarkRequestResponseActor(b *testing.B) {
154	var pinger, ponger Inbox
155	done := make(chan struct{})
156	idx := 0
157	var ping, pong func()
158	ping = func() {
159		if idx < b.N {
160			idx++
161			ponger.Act(&pinger, pong)
162			pinger.Act(nil, ping) // loop asynchronously
163		} else {
164			ponger.Act(&pinger, func() {
165				pinger.Act(nil, func() {
166					close(done)
167				})
168			})
169		}
170	}
171	pong = func() {
172		pinger.Act(nil, func() {}) // send a response without backpressure
173	}
174	pinger.Act(nil, ping)
175	<-done
176}
177
178func BenchmarkRequestResponseChannel(b *testing.B) {
179	done := make(chan struct{})
180	toPing := make(chan func(), 1)
181	toPong := make(chan func(), 1)
182	defer close(toPing)
183	defer close(toPong)
184	var ping func()
185	var pong func()
186	ping = func() {
187		for idx := 0; idx < b.N; idx++ {
188			toPong <- pong
189			f := <-toPing
190			f()
191		}
192		toPong <- func() {
193			toPing <- func() {
194				close(done)
195			}
196		}
197	}
198	pong = func() {
199		toPing <- func() {}
200	}
201	go func() {
202		for f := range toPing {
203			f()
204		}
205	}()
206	go func() {
207		for f := range toPong {
208			f()
209		}
210	}()
211	toPing <- ping
212	<-done
213}
214
215func BenchmarkBlock(b *testing.B) {
216	var a Inbox
217	for i := 0; i < b.N; i++ {
218		Block(&a, func() {})
219	}
220}
221