about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-02-26 22:56:06 -0800
committerKartik K. Agaram <vc@akkartik.com>2022-02-26 22:57:48 -0800
commit891bced5443cde47f51626d962e87df7d084a64c (patch)
tree84499120b625d4ae9f8199fb95176ae17023e6dd /src
parent42526cb15d3cf5798b19e6063443a8260d8bd26f (diff)
downloadteliva-891bced5443cde47f51626d962e87df7d084a64c.tar.gz
always run unit tests for channels and tasks
Diffstat (limited to 'src')
-rw-r--r--src/task.lua426
1 files changed, 210 insertions, 216 deletions
diff --git a/src/task.lua b/src/task.lua
index 81aa63e..09fa10a 100644
--- a/src/task.lua
+++ b/src/task.lua
@@ -383,250 +383,244 @@ _M.NOP       = NOP
 ----------------------------------------------------------------------------
 ----------------------------------------------------------------------------
 -- Tests
---
--- To run:
---    $ lua task.lua
 
 local task = _M
 
-local tests = {
-   counter = function ()
-      local done
-      local function counter(c)
-         local i = 1
-         while true do
-            c:send(i)
-            i = i + 1
-         end
-      end
-      local function main()
-         local c = task.Channel:new()
-         task.spawn(counter, c)
-         assert(c:recv() == 1)
-         assert(c:recv() == 2)
-         assert(c:recv() == 3)
-         assert(c:recv() == 4)
-         assert(c:recv() == 5)
-         done = true
-      end
-      task.spawn(main)
-      task.scheduler()
-      assert(done)
-   end,
-
-   nonblocking_channel = function()
-      local done
-      local function main()
-         local b = task.Channel:new()
-         assert(b:nbsend(1) == false)
-         assert(b:nbrecv() == false)
-
-         local c = task.Channel:new(1)
-         assert(c:nbrecv() == false)
-         assert(c:nbsend(1) == true)
-         assert(c:nbsend(1) == false)
-         local r, v = c:nbrecv()
-         assert(r == true)
-         assert(v == 1)
-         assert(c:nbrecv() == false)
-         done = true
-      end
-      task.spawn(main)
-      task.scheduler()
-      assert(done)
-   end,
-
-   concurrent_send_and_recv = function()
-      local l = {}
-      local function a(c, name)
-         -- Blocking send and recv from the same process
-         local alt = {{c = c, op = task.SEND, p = 1},
-                      {c = c, op = task.RECV}}
-         local i, v = task.chanalt(alt, true)
-         local k = string.format('%s %s', name, i == 1 and "send" or "recv")
-         l[k] = (l[k] or 0) + 1
+function test_counter()
+   local done
+   local function counter(c)
+      local i = 1
+      while true do
+         c:send(i)
+         i = i + 1
       end
+   end
+   local function main()
+      local c = task.Channel:new()
+      task.spawn(counter, c)
+      assert(c:recv() == 1)
+      assert(c:recv() == 2)
+      assert(c:recv() == 3)
+      assert(c:recv() == 4)
+      assert(c:recv() == 5)
+      done = true
+   end
+   task.spawn(main)
+   task.scheduler()
+   assert(done)
+end
 
-      for i = 0, 1000 do
-         -- On Mac OS X in lua 5.1 initializing seed with a
-         -- predictable value makes no sense. For all seeds from 1 to
-         -- 1000 the result of math.random(1,3) is _exactly_ the same!
-         -- So beware, when seeding!
-         -- math.randomseed(i)
-         local c = task.Channel:new()
-         task.spawn(a, c, "a")
-         task.spawn(a, c, "b")
-         task.scheduler()
-      end
+function test_nonblocking_channel()
+   local done
+   local function main()
+      local b = task.Channel:new()
+      assert(b:nbsend(1) == false)
+      assert(b:nbrecv() == false)
+
+      local c = task.Channel:new(1)
+      assert(c:nbrecv() == false)
+      assert(c:nbsend(1) == true)
+      assert(c:nbsend(1) == false)
+      local r, v = c:nbrecv()
+      assert(r == true)
+      assert(v == 1)
+      assert(c:nbrecv() == false)
+      done = true
+   end
+   task.spawn(main)
+   task.scheduler()
+   assert(done)
+end
 
-      -- Make sure we have randomness, that is: events occur in both
-      -- orders in 1000 runs
-      assert(l['a recv'] > 0)
-      assert(l['a send'] > 0)
-      assert(l['b recv'] > 0)
-      assert(l['b send'] > 0)
-   end,
+function test_concurrent_send_and_recv()
+   local l = {}
+   local function a(c, name)
+      -- Blocking send and recv from the same process
+      local alt = {{c = c, op = task.SEND, p = 1},
+                   {c = c, op = task.RECV}}
+      local i, v = task.chanalt(alt, true)
+      local k = string.format('%s %s', name, i == 1 and "send" or "recv")
+      l[k] = (l[k] or 0) + 1
+   end
 
-   channels_from_a_coroutine = function()
-      local done
+   for i = 0, 1000 do
+      -- On Mac OS X in lua 5.1 initializing seed with a
+      -- predictable value makes no sense. For all seeds from 1 to
+      -- 1000 the result of math.random(1,3) is _exactly_ the same!
+      -- So beware, when seeding!
+      -- math.randomseed(i)
       local c = task.Channel:new()
-      local function a()
-         for i = 1, 100 do
-            c:send(i)
-         end
-      end
-      local function b()
-         assert(c:recv() == 1)
-         assert(c:recv() == 2)
-         assert(c:recv() == 3)
-         assert(c:recv() == 4)
-         assert(c:recv() == 5)
-         done = true
-      end
-      local a_co = coroutine.create(a)
-      local b_co = coroutine.create(b)
-      coroutine.resume(a_co)
-      coroutine.resume(b_co)
+      task.spawn(a, c, "a")
+      task.spawn(a, c, "b")
       task.scheduler()
-      assert(done)
-   end,
+   end
 
-   fibonacci = function()
-      local done
-      local function fib(c)
-         local x, y = 0, 1
-         while true do
-            c:send(x)
-            x, y = y, x + y
-         end
-      end
-      local function main(c)
-         assert(c:recv() == 0)
-         assert(c:recv() == 1)
-         assert(c:recv() == 1)
-         assert(c:recv() == 2)
-         assert(c:recv() == 3)
-         assert(c:recv() == 5)
-         assert(c:recv() == 8)
-         assert(c:recv() == 13)
-         assert(c:recv() == 21)
-         assert(c:recv() == 34)
-         done = true
+   -- Make sure we have randomness, that is: events occur in both
+   -- orders in 1000 runs
+   assert(l['a recv'] > 0)
+   assert(l['a send'] > 0)
+   assert(l['b recv'] > 0)
+   assert(l['b send'] > 0)
+end
+
+function test_channels_from_a_coroutine()
+   local done
+   local c = task.Channel:new()
+   local function a()
+      for i = 1, 100 do
+         c:send(i)
       end
+   end
+   local function b()
+      assert(c:recv() == 1)
+      assert(c:recv() == 2)
+      assert(c:recv() == 3)
+      assert(c:recv() == 4)
+      assert(c:recv() == 5)
+      done = true
+   end
+   local a_co = coroutine.create(a)
+   local b_co = coroutine.create(b)
+   coroutine.resume(a_co)
+   coroutine.resume(b_co)
+   task.scheduler()
+   assert(done)
+end
 
-      local c = task.Channel:new()
-      task.spawn(fib, c)
-      task.spawn(main, c)
-      task.scheduler()
-      assert(done)
-   end,
+function test_fibonacci()
+   local done
+   local function fib(c)
+      local x, y = 0, 1
+      while true do
+         c:send(x)
+         x, y = y, x + y
+      end
+   end
+   local function main(c)
+      assert(c:recv() == 0)
+      assert(c:recv() == 1)
+      assert(c:recv() == 1)
+      assert(c:recv() == 2)
+      assert(c:recv() == 3)
+      assert(c:recv() == 5)
+      assert(c:recv() == 8)
+      assert(c:recv() == 13)
+      assert(c:recv() == 21)
+      assert(c:recv() == 34)
+      done = true
+   end
 
-   non_blocking_chanalt = function()
-      local done
-      local function main()
-         local c = task.Channel:new()
-         local alts = {{c = c, op = task.RECV},
-                       {c = c, op = task.NOP},
-                       {c = c, op = task.SEND, p = 1}}
-         assert(task.chanalt(alts, false) == nil)
-
-         local c = task.Channel:new(1)
-         local alts = {{c = c, op = task.RECV},
-                       {c = c, op = task.NOP},
-                       {c = c, op = task.SEND, p = 1}}
-         assert(task.chanalt(alts, false) == 3)
-         assert(task.chanalt(alts, false) == 1)
-
-         local alts = {{c = c, op = task.NOP}}
-         assert(task.chanalt(alts, false) == nil)
+   local c = task.Channel:new()
+   task.spawn(fib, c)
+   task.spawn(main, c)
+   task.scheduler()
+   assert(done)
+end
 
-         done = true
-      end
-      task.spawn(main)
-      task.scheduler()
-      assert(done)
-   end,
+function test_non_blocking_chanalt()
+   local done
+   local function main()
+      local c = task.Channel:new()
+      local alts = {{c = c, op = task.RECV},
+                    {c = c, op = task.NOP},
+                    {c = c, op = task.SEND, p = 1}}
+      assert(task.chanalt(alts, false) == nil)
+
+      local c = task.Channel:new(1)
+      local alts = {{c = c, op = task.RECV},
+                    {c = c, op = task.NOP},
+                    {c = c, op = task.SEND, p = 1}}
+      assert(task.chanalt(alts, false) == 3)
+      assert(task.chanalt(alts, false) == 1)
+
+      local alts = {{c = c, op = task.NOP}}
+      assert(task.chanalt(alts, false) == nil)
+
+      done = true
+   end
+   task.spawn(main)
+   task.scheduler()
+   assert(done)
+end
 
-   -- Apparently it's not really a Sieve of Eratosthenes:
-   --   http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
-   eratosthenes_sieve = function()
-      local done
-      local function counter(c)
-         local i = 2
-         while true do
-            c:send(i)
-            i = i + 1
-         end
+-- Apparently it's not really a Sieve of Eratosthenes:
+--   http://www.cs.hmc.edu/~oneill/papers/Sieve-JFP.pdf
+function test_eratosthenes_sieve()
+   local done
+   local function counter(c)
+      local i = 2
+      while true do
+         c:send(i)
+         i = i + 1
       end
+   end
 
-      local function filter(p, recv_ch, send_ch)
-         while true do
-            local i = recv_ch:recv()
-            if i % p ~= 0 then
-               send_ch:send(i)
-            end
+   local function filter(p, recv_ch, send_ch)
+      while true do
+         local i = recv_ch:recv()
+         if i % p ~= 0 then
+            send_ch:send(i)
          end
       end
+   end
 
-      local function sieve(primes_ch)
-         local c = task.Channel:new()
-         task.spawn(counter, c)
-         while true do
-            local p, newc = c:recv(), task.Channel:new()
-            primes_ch:send(p)
-            task.spawn(filter, p, c, newc)
-            c = newc
-         end
+   local function sieve(primes_ch)
+      local c = task.Channel:new()
+      task.spawn(counter, c)
+      while true do
+         local p, newc = c:recv(), task.Channel:new()
+         primes_ch:send(p)
+         task.spawn(filter, p, c, newc)
+         c = newc
       end
+   end
 
-      local function main()
-         local primes = task.Channel:new()
-         task.spawn(sieve, primes)
-         assert(primes:recv() == 2)
-         assert(primes:recv() == 3)
-         assert(primes:recv() == 5)
-         assert(primes:recv() == 7)
-         assert(primes:recv() == 11)
-         assert(primes:recv() == 13)
-         done = true
-      end
+   local function main()
+      local primes = task.Channel:new()
+      task.spawn(sieve, primes)
+      assert(primes:recv() == 2)
+      assert(primes:recv() == 3)
+      assert(primes:recv() == 5)
+      assert(primes:recv() == 7)
+      assert(primes:recv() == 11)
+      assert(primes:recv() == 13)
+      done = true
+   end
 
-      task.spawn(main)
-      task.scheduler()
-      assert(done)
-   end,
+   task.spawn(main)
+   task.scheduler()
+   assert(done)
+end
 
-   channel_as_iterator = function()
-      local done
-      local function counter(c)
-         local i = 2
-         while true do
-            c:send(i)
-            i = i + 1
-         end
+function test_channel_as_iterator()
+   local done
+   local function counter(c)
+      local i = 2
+      while true do
+         c:send(i)
+         i = i + 1
       end
+   end
 
-      local function main()
-         local numbers = task.Channel:new()
-         task.spawn(counter, numbers)
-         for _, j in numbers() do
-            if j == 100 then
-               break
-            end
-            done = true
+   local function main()
+      local numbers = task.Channel:new()
+      task.spawn(counter, numbers)
+      for _, j in numbers() do
+         if j == 100 then
+            break
          end
-      end
-      if _VERSION == "Lua 5.1" then
-         -- sorry, this doesn't work in 5.1
-         print('skipping... (5.1 unsupported)')
          done = true
-      else
-         task.spawn(main)
-         task.scheduler()
       end
-      assert(done)
-   end,
-
-}
+   end
+   if _VERSION == "Lua 5.1" then
+      -- sorry, this test doesn't work in 5.1
+      print('skipping... (5.1 unsupported)')
+      done = true
+   else
+      task.spawn(main)
+      task.scheduler()
+   end
+   assert(done)
+end
 
 return _M