diff options
Diffstat (limited to 'tests/cancel.lua')
| -rw-r--r-- | tests/cancel.lua | 212 |
1 files changed, 123 insertions, 89 deletions
diff --git a/tests/cancel.lua b/tests/cancel.lua index 0d9d143..4e57184 100644 --- a/tests/cancel.lua +++ b/tests/cancel.lua | |||
| @@ -1,36 +1,47 @@ | |||
| 1 | local lanes = require "lanes" .configure{ with_timers = false} | 1 | local which_tests, remaining_tests = {}, {} |
| 2 | 2 | for k,v in ipairs{...} do | |
| 3 | local linda = lanes.linda() | 3 | print("got arg:", type(v), tostring(v)) |
| 4 | which_tests[v] = true | ||
| 5 | remaining_tests[v] = true | ||
| 6 | end | ||
| 4 | 7 | ||
| 5 | --#################################################################### | 8 | --#################################################################### |
| 6 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | ||
| 7 | |||
| 8 | -- get a lock and a atomic operator | ||
| 9 | local lock = lanes.genlock( linda, "lock", 1) | ||
| 10 | local atomic = lanes.genatomic( linda, "atomic") | ||
| 11 | |||
| 12 | -- check that cancelled lindas give cancel_error as they should | ||
| 13 | linda:cancel() | ||
| 14 | assert( linda:get( "empty") == lanes.cancel_error) | ||
| 15 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | ||
| 16 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | ||
| 17 | |||
| 18 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | ||
| 19 | assert( lock( 1) == lanes.cancel_error) | ||
| 20 | assert( lock( -1) == lanes.cancel_error) | ||
| 21 | assert( atomic( 1) == lanes.cancel_error) | ||
| 22 | |||
| 23 | -- reset the linda so that the other tests work | ||
| 24 | linda:cancel( "none") | ||
| 25 | linda:limit( "lock", -1) | ||
| 26 | linda:set( "lock") | ||
| 27 | linda:limit( "atomic", -1) | ||
| 28 | linda:set( "atomic") | ||
| 29 | 9 | ||
| 10 | local lanes = require "lanes" .configure{ with_timers = false} | ||
| 11 | |||
| 12 | local linda = lanes.linda() | ||
| 30 | -- a numeric value to read | 13 | -- a numeric value to read |
| 31 | linda:set( "val", 33.0) | 14 | linda:set( "val", 33.0) |
| 32 | 15 | ||
| 33 | print "test OK" | 16 | --#################################################################### |
| 17 | if not next(which_tests) or which_tests.genlock then | ||
| 18 | remaining_tests.genlock = nil | ||
| 19 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | ||
| 20 | |||
| 21 | -- get a lock and a atomic operator | ||
| 22 | local lock = lanes.genlock( linda, "lock", 1) | ||
| 23 | local atomic = lanes.genatomic( linda, "atomic") | ||
| 24 | |||
| 25 | -- check that cancelled lindas give cancel_error as they should | ||
| 26 | linda:cancel() | ||
| 27 | assert( linda:get( "empty") == lanes.cancel_error) | ||
| 28 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | ||
| 29 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | ||
| 30 | |||
| 31 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | ||
| 32 | assert( lock( 1) == lanes.cancel_error) | ||
| 33 | assert( lock( -1) == lanes.cancel_error) | ||
| 34 | assert( atomic( 1) == lanes.cancel_error) | ||
| 35 | |||
| 36 | -- reset the linda so that the other tests work | ||
| 37 | linda:cancel( "none") | ||
| 38 | linda:limit( "lock", -1) | ||
| 39 | linda:set( "lock") | ||
| 40 | linda:limit( "atomic", -1) | ||
| 41 | linda:set( "atomic") | ||
| 42 | |||
| 43 | print "test OK" | ||
| 44 | end | ||
| 34 | --#################################################################### | 45 | --#################################################################### |
| 35 | 46 | ||
| 36 | local waitCancellation = function( h, expected_status) | 47 | local waitCancellation = function( h, expected_status) |
| @@ -119,92 +130,115 @@ end | |||
| 119 | --#################################################################### | 130 | --#################################################################### |
| 120 | --#################################################################### | 131 | --#################################################################### |
| 121 | 132 | ||
| 122 | print "\n\n####################################################################\nbegin linda cancel test\n" | 133 | if not next(which_tests) or which_tests.linda then |
| 123 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda | 134 | remaining_tests.linda = nil |
| 124 | 135 | print "\n\n####################################################################\nbegin linda cancel test\n" | |
| 125 | print "wait 1s" | 136 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda |
| 126 | linda:receive( 1, "yeah") | ||
| 127 | |||
| 128 | -- linda cancel: linda:receive() returns cancel_error immediately | ||
| 129 | linda:cancel( "both") | ||
| 130 | 137 | ||
| 131 | -- wait until cancellation is effective. | 138 | print "wait 1s" |
| 132 | waitCancellation( h, "done") | 139 | linda:receive( 1, "yeah") |
| 133 | 140 | ||
| 134 | -- reset the linda so that the other tests work | 141 | -- linda cancel: linda:receive() returns cancel_error immediately |
| 135 | linda:cancel( "none") | 142 | print "cancelling" |
| 143 | linda:cancel( "both") | ||
| 136 | 144 | ||
| 137 | print "\n\n####################################################################\nbegin soft cancel test\n" | 145 | -- wait until cancellation is effective. |
| 138 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda | 146 | waitCancellation( h, "done") |
| 139 | 147 | ||
| 140 | print "wait 1s" | 148 | -- reset the linda so that the other tests work |
| 141 | linda:receive( 1, "yeah") | 149 | linda:cancel( "none") |
| 150 | end | ||
| 142 | 151 | ||
| 143 | -- soft cancel, no awakening of waiting linda operations, should timeout | 152 | if not next(which_tests) or which_tests.soft then |
| 144 | local a, b = h:cancel( "soft", 1, false) | 153 | remaining_tests.soft = nil |
| 145 | -- cancellation should fail as the lane is still waiting on its linda | 154 | print "\n\n####################################################################\nbegin soft cancel test\n" |
| 146 | assert( a == false and b == "timeout") | 155 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda |
| 147 | waitCancellation( h, "waiting") | ||
| 148 | 156 | ||
| 149 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. | 157 | print "wait 1s" |
| 150 | h:cancel( "soft", true) | 158 | linda:receive( 1, "yeah") |
| 151 | 159 | ||
| 152 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 160 | -- soft cancel, no awakening of waiting linda operations, should timeout |
| 153 | waitCancellation( h, "done") | 161 | local a, b = h:cancel( "soft", 1, false) |
| 162 | -- cancellation should fail as the lane is still waiting on its linda | ||
| 163 | assert( a == false and b == "timeout") | ||
| 164 | waitCancellation( h, "waiting") | ||
| 154 | 165 | ||
| 155 | -- do return end | 166 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. |
| 167 | print "cancelling" | ||
| 168 | h:cancel( "soft", true) | ||
| 156 | 169 | ||
| 157 | print "\n\n####################################################################\nbegin hook cancel test\n" | 170 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
| 158 | h = lanes.gen( "*", protectedBody)( "get", 300000) | 171 | waitCancellation( h, "done") |
| 159 | print "wait 2s" | 172 | end |
| 160 | linda:receive( 2, "yeah") | ||
| 161 | 173 | ||
| 162 | -- count hook cancel after 3 instructions | 174 | if not next(which_tests) or which_tests.hook then |
| 163 | h:cancel( "count", 300, 5.0) | 175 | remaining_tests.hook = nil |
| 176 | print "\n\n####################################################################\nbegin hook cancel test\n" | ||
| 177 | h = lanes.gen( "*", protectedBody)( "get", 300000) | ||
| 178 | print "wait 2s" | ||
| 179 | linda:receive( 2, "yeah") | ||
| 164 | 180 | ||
| 165 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 181 | -- count hook cancel after some instruction instructions |
| 166 | waitCancellation( h, "cancelled") | 182 | print "cancelling" |
| 183 | h:cancel( "line", 300, 5.0) | ||
| 167 | 184 | ||
| 168 | print "\n\n####################################################################\nbegin hard cancel test\n" | 185 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
| 169 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | 186 | waitCancellation( h, "cancelled") |
| 187 | end | ||
| 170 | 188 | ||
| 171 | -- wait 2s before cancelling the lane | 189 | if not next(which_tests) or which_tests.hard then |
| 172 | print "wait 2s" | 190 | remaining_tests.hard = nil |
| 173 | linda:receive( 2, "yeah") | 191 | print "\n\n####################################################################\nbegin hard cancel test\n" |
| 192 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | ||
| 174 | 193 | ||
| 175 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 194 | -- wait 2s before cancelling the lane |
| 176 | h:cancel() | 195 | print "wait 2s" |
| 196 | linda:receive( 2, "yeah") | ||
| 177 | 197 | ||
| 178 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 198 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
| 179 | waitCancellation( h, "cancelled") | 199 | print "cancelling" |
| 200 | h:cancel() | ||
| 180 | 201 | ||
| 181 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" | 202 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
| 182 | h = lanes.gen( "*", laneBody)( "receive", nil) | 203 | waitCancellation( h, "cancelled") |
| 204 | end | ||
| 183 | 205 | ||
| 184 | -- wait 2s before cancelling the lane | 206 | if not next(which_tests) or which_tests.hard_unprotected then |
| 185 | print "wait 2s" | 207 | remaining_tests.hard_unprotected = nil |
| 186 | linda:receive( 2, "yeah") | 208 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" |
| 209 | h = lanes.gen( "*", laneBody)( "receive", nil) | ||
| 187 | 210 | ||
| 188 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 211 | -- wait 2s before cancelling the lane |
| 189 | h:cancel() | 212 | print "wait 2s" |
| 213 | linda:receive( 2, "yeah") | ||
| 190 | 214 | ||
| 191 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 215 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
| 192 | waitCancellation( h, "cancelled") | 216 | print "cancelling" |
| 217 | h:cancel() | ||
| 193 | 218 | ||
| 194 | print "\n\n####################################################################\nbegin kill cancel test\n" | 219 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
| 195 | h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane | 220 | waitCancellation( h, "cancelled") |
| 221 | end | ||
| 196 | 222 | ||
| 197 | -- wait 1/3s before cancelling the lane, before the busy loop can finish | 223 | if not next(which_tests) or which_tests.kill then |
| 198 | print "wait 0.3s" | 224 | remaining_tests.kill = nil |
| 199 | linda:receive( 0.3, "yeah") | 225 | print "\n\n####################################################################\nbegin kill cancel test\n" |
| 226 | h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane | ||
| 200 | 227 | ||
| 201 | -- hard cancel with kill: the lane thread will be forcefully terminated | 228 | -- wait 1/3s before cancelling the lane, before the busy loop can finish |
| 202 | h:cancel( true) | 229 | print "wait 0.3s" |
| 230 | linda:receive( 0.3, "yeah") | ||
| 203 | 231 | ||
| 204 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 232 | -- hard cancel with kill: the lane thread will be forcefully terminated. kill timeout is pthread-specific |
| 205 | waitCancellation( h, "killed") | 233 | print "cancelling" |
| 234 | h:cancel( true, 1.0) | ||
| 206 | 235 | ||
| 236 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | ||
| 237 | waitCancellation( h, "killed") | ||
| 238 | end | ||
| 207 | --#################################################################### | 239 | --#################################################################### |
| 208 | 240 | ||
| 209 | print "\ndone" | 241 | local unknown_test, val = next(remaining_tests) |
| 242 | assert(not unknown_test, tostring(unknown_test) .. " test is unknown") | ||
| 210 | 243 | ||
| 244 | print "\nTHE END" | ||
