# vim:set ft= ts=4 sw=4 et fdm=marker: use Test::Nginx::Socket::Lua::Stream;use t::StapThread; our $GCScript = $t::StapThread::GCScript; our $StapScript = $t::StapThread::StapScript; repeat_each(2); plan tests => repeat_each() * (blocks() * 5 + 1); $ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8'; $ENV{TEST_NGINX_MEMCACHED_PORT} ||= '11211'; #no_shuffle(); no_long_string(); run_tests(); __DATA__ === TEST 1: kill pending sleep --- stream_server_config content_by_lua_block { function f() ngx.say("hello from f()") ngx.sleep(1) end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) collectgarbage() local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end ngx.say("killed") local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end } --- stap2 eval: $::StapScript --- stap eval: $::GCScript --- stap_out create 2 in 1 spawn user thread 2 in 1 delete thread 2 terminate 1: ok delete thread 1 --- stream_response hello from f() thread created: running killed failed to kill thread: already waited or killed --- no_error_log [error] --- error_log lua clean up the timer for pending ngx.sleep === TEST 2: already waited --- stream_server_config content_by_lua_block { function f() ngx.say("hello from f()") ngx.sleep(0.001) return 32 end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) collectgarbage() local ok, res = ngx.thread.wait(t) if not ok then ngx.say("failed to kill thread: ", res) return end ngx.say("waited: ", res) local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end } --- stap2 eval: $::StapScript --- stap eval: $::GCScript --- stap_out create 2 in 1 spawn user thread 2 in 1 terminate 2: ok delete thread 2 terminate 1: ok delete thread 1 --- stream_response hello from f() thread created: running waited: 32 failed to kill thread: already waited or killed --- no_error_log [error] lua clean up the timer for pending ngx.sleep === TEST 3: kill pending resolver --- stream_server_config resolver 127.0.0.2:12345; resolver_timeout 5ms; content_by_lua_block { function f() local sock = ngx.socket.tcp() sock:connect("some.agentzh.org", 80) end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) collectgarbage() local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end ngx.say("killed") } --- stap2 eval: $::StapScript --- stap eval: $::GCScript --- stap_out create 2 in 1 spawn user thread 2 in 1 delete thread 2 terminate 1: ok delete thread 1 --- stream_response thread created: running killed --- no_error_log [error] --- error_log lua tcp socket abort resolver === TEST 4: kill pending connect --- stream_server_config resolver $TEST_NGINX_RESOLVER ipv6=off; content_by_lua_block { local ready = false function f() local sock = ngx.socket.tcp() sock:connect("agentzh.org", 80) sock:close() ready = true sock:settimeout(10000) sock:connect("127.0.0.2", 12345) end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) collectgarbage() while not ready do ngx.sleep(0.001) end local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end ngx.say("killed") } --- stap2 eval: $::StapScript --- stap eval: $::GCScript --- stap_out create 2 in 1 spawn user thread 2 in 1 delete thread 2 terminate 1: ok delete thread 1 --- stream_response thread created: running killed --- no_error_log [error] lua tcp socket abort resolver --- grep_error_log: stream lua finalize socket --- grep_error_log_out stream lua finalize socket stream lua finalize socket --- error_log === TEST 5: kill a thread already terminated --- stream_server_config content_by_lua_block { function f() return end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) collectgarbage() local ok, err = ngx.thread.kill(t) if not ok then ngx.say("failed to kill thread: ", err) return end ngx.say("killed") } --- stap2 eval: $::StapScript --- stream_response thread created: zombie failed to kill thread: already terminated --- no_error_log [error] [alert] lua tcp socket abort resolver --- error_log === TEST 6: kill self --- stream_server_config content_by_lua_block { local ok, err = ngx.thread.kill(coroutine.running()) if not ok then ngx.say("failed to kill main thread: ", err) else ngx.say("killed main thread.") end function f() local ok, err = ngx.thread.kill(coroutine.running()) if not ok then ngx.say("failed to kill user thread: ", err) else ngx.say("user thread thread.") end end local t, err = ngx.thread.spawn(f) if not t then ngx.say("failed to spawn thread: ", err) return end ngx.say("thread created: ", coroutine.status(t)) } --- stap2 eval: $::StapScript --- stream_response failed to kill main thread: not user thread failed to kill user thread: killer not parent thread created: zombie --- no_error_log [error] [alert] stream lua tcp socket abort resolver --- error_log