channellib_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. package lua
  2. import (
  3. "reflect"
  4. "sync"
  5. "testing"
  6. "time"
  7. )
  8. func TestChannelMake(t *testing.T) {
  9. L := NewState()
  10. defer L.Close()
  11. errorIfScriptFail(t, L, `
  12. ch = channel.make()
  13. `)
  14. obj := L.GetGlobal("ch")
  15. ch, ok := obj.(LChannel)
  16. errorIfFalse(t, ok, "channel expected")
  17. errorIfNotEqual(t, 0, reflect.ValueOf(ch).Cap())
  18. close(ch)
  19. errorIfScriptFail(t, L, `
  20. ch = channel.make(10)
  21. `)
  22. obj = L.GetGlobal("ch")
  23. ch, _ = obj.(LChannel)
  24. errorIfNotEqual(t, 10, reflect.ValueOf(ch).Cap())
  25. close(ch)
  26. }
  27. func TestChannelSelectError(t *testing.T) {
  28. L := NewState()
  29. defer L.Close()
  30. errorIfScriptFail(t, L, `ch = channel.make()`)
  31. errorIfScriptNotFail(t, L, `channel.select({1,2,3})`, "invalid select case")
  32. errorIfScriptNotFail(t, L, `channel.select({"<-|", 1, 3})`, "invalid select case")
  33. errorIfScriptNotFail(t, L, `channel.select({"<-|", ch, function() end})`, "can not send a function")
  34. errorIfScriptNotFail(t, L, `channel.select({"|<-", 1, 3})`, "invalid select case")
  35. errorIfScriptNotFail(t, L, `channel.select({"<-->", 1, 3})`, "invalid channel direction")
  36. errorIfScriptFail(t, L, `ch:close()`)
  37. }
  38. func TestChannelSelect1(t *testing.T) {
  39. var result LValue
  40. var wg sync.WaitGroup
  41. receiver := func(ch, quit chan LValue) {
  42. defer wg.Done()
  43. L := NewState()
  44. defer L.Close()
  45. L.SetGlobal("ch", LChannel(ch))
  46. L.SetGlobal("quit", LChannel(quit))
  47. if err := L.DoString(`
  48. buf = ""
  49. local exit = false
  50. while not exit do
  51. channel.select(
  52. {"|<-", ch, function(ok, v)
  53. if not ok then
  54. buf = buf .. "channel closed"
  55. exit = true
  56. else
  57. buf = buf .. "received:" .. v
  58. end
  59. end},
  60. {"|<-", quit, function(ok, v)
  61. buf = buf .. "quit"
  62. end}
  63. )
  64. end
  65. `); err != nil {
  66. panic(err)
  67. }
  68. result = L.GetGlobal("buf")
  69. }
  70. sender := func(ch, quit chan LValue) {
  71. defer wg.Done()
  72. L := NewState()
  73. defer L.Close()
  74. L.SetGlobal("ch", LChannel(ch))
  75. L.SetGlobal("quit", LChannel(quit))
  76. if err := L.DoString(`
  77. ch:send("1")
  78. ch:send("2")
  79. `); err != nil {
  80. panic(err)
  81. }
  82. ch <- LString("3")
  83. quit <- LTrue
  84. time.Sleep(1 * time.Second)
  85. close(ch)
  86. }
  87. ch := make(chan LValue)
  88. quit := make(chan LValue)
  89. wg.Add(2)
  90. go receiver(ch, quit)
  91. go sender(ch, quit)
  92. wg.Wait()
  93. lstr, ok := result.(LString)
  94. errorIfFalse(t, ok, "must be string")
  95. str := string(lstr)
  96. errorIfNotEqual(t, "received:1received:2received:3quitchannel closed", str)
  97. }
  98. func TestChannelSelect2(t *testing.T) {
  99. var wg sync.WaitGroup
  100. receiver := func(ch, quit chan LValue) {
  101. defer wg.Done()
  102. L := NewState()
  103. defer L.Close()
  104. L.SetGlobal("ch", LChannel(ch))
  105. L.SetGlobal("quit", LChannel(quit))
  106. errorIfScriptFail(t, L, `
  107. idx, rcv, ok = channel.select(
  108. {"|<-", ch},
  109. {"|<-", quit}
  110. )
  111. assert(idx == 1)
  112. assert(rcv == "1")
  113. assert(ok)
  114. idx, rcv, ok = channel.select(
  115. {"|<-", ch},
  116. {"|<-", quit}
  117. )
  118. assert(idx == 1)
  119. assert(rcv == nil)
  120. assert(not ok)
  121. `)
  122. }
  123. sender := func(ch, quit chan LValue) {
  124. defer wg.Done()
  125. L := NewState()
  126. defer L.Close()
  127. L.SetGlobal("ch", LChannel(ch))
  128. L.SetGlobal("quit", LChannel(quit))
  129. errorIfScriptFail(t, L, `ch:send("1")`)
  130. errorIfScriptFail(t, L, `ch:close()`)
  131. }
  132. ch := make(chan LValue)
  133. quit := make(chan LValue)
  134. wg.Add(2)
  135. go receiver(ch, quit)
  136. go sender(ch, quit)
  137. wg.Wait()
  138. }
  139. func TestChannelSelect3(t *testing.T) {
  140. var wg sync.WaitGroup
  141. receiver := func(ch chan LValue) {
  142. defer wg.Done()
  143. L := NewState()
  144. defer L.Close()
  145. L.SetGlobal("ch", LChannel(ch))
  146. errorIfScriptFail(t, L, `
  147. ok = true
  148. while ok do
  149. idx, rcv, ok = channel.select(
  150. {"|<-", ch}
  151. )
  152. end
  153. `)
  154. }
  155. sender := func(ch chan LValue) {
  156. defer wg.Done()
  157. L := NewState()
  158. defer L.Close()
  159. L.SetGlobal("ch", LChannel(ch))
  160. errorIfScriptFail(t, L, `
  161. ok = false
  162. channel.select(
  163. {"<-|", ch, "1", function(v)
  164. ok = true
  165. end}
  166. )
  167. assert(ok)
  168. idx, rcv, ok = channel.select(
  169. {"<-|", ch, "1"}
  170. )
  171. assert(idx == 1)
  172. ch:close()
  173. `)
  174. }
  175. ch := make(chan LValue)
  176. wg.Add(2)
  177. go receiver(ch)
  178. time.Sleep(1)
  179. go sender(ch)
  180. wg.Wait()
  181. }
  182. func TestChannelSelect4(t *testing.T) {
  183. var wg sync.WaitGroup
  184. receiver := func(ch chan LValue) {
  185. defer wg.Done()
  186. L := NewState()
  187. defer L.Close()
  188. L.SetGlobal("ch", LChannel(ch))
  189. errorIfScriptFail(t, L, `
  190. idx, rcv, ok = channel.select(
  191. {"|<-", ch},
  192. {"default"}
  193. )
  194. assert(idx == 2)
  195. called = false
  196. idx, rcv, ok = channel.select(
  197. {"|<-", ch},
  198. {"default", function()
  199. called = true
  200. end}
  201. )
  202. assert(called)
  203. ch:close()
  204. `)
  205. }
  206. ch := make(chan LValue)
  207. wg.Add(1)
  208. go receiver(ch)
  209. wg.Wait()
  210. }
  211. func TestChannelSendReceive1(t *testing.T) {
  212. var wg sync.WaitGroup
  213. receiver := func(ch chan LValue) {
  214. defer wg.Done()
  215. L := NewState()
  216. defer L.Close()
  217. L.SetGlobal("ch", LChannel(ch))
  218. errorIfScriptFail(t, L, `
  219. local ok, v = ch:receive()
  220. assert(ok)
  221. assert(v == "1")
  222. `)
  223. time.Sleep(1 * time.Second)
  224. errorIfScriptFail(t, L, `
  225. local ok, v = ch:receive()
  226. assert(not ok)
  227. assert(v == nil)
  228. `)
  229. }
  230. sender := func(ch chan LValue) {
  231. defer wg.Done()
  232. L := NewState()
  233. defer L.Close()
  234. L.SetGlobal("ch", LChannel(ch))
  235. errorIfScriptFail(t, L, `ch:send("1")`)
  236. errorIfScriptNotFail(t, L, `ch:send(function() end)`, "can not send a function")
  237. errorIfScriptFail(t, L, `ch:close()`)
  238. }
  239. ch := make(chan LValue)
  240. wg.Add(2)
  241. go receiver(ch)
  242. go sender(ch)
  243. wg.Wait()
  244. }