Skip to content

Commit 43c08e8

Browse files
committed
tests: 091-coroutine.t: ported ngx_http_lua test cases for 'coroutine.wrap()' propagating errors and 'coroutine.resume()' not logging runtime errors.
1 parent 5da8088 commit 43c08e8

File tree

1 file changed

+313
-1
lines changed

1 file changed

+313
-1
lines changed

t/091-coroutine.t

Lines changed: 313 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use Test::Nginx::Socket::Lua::Stream;
44

55
repeat_each(2);
66

7-
plan tests => repeat_each() * (blocks() * 3 + 4);
7+
plan tests => repeat_each() * (blocks() * 3 + 27);
88

99
$ENV{TEST_NGINX_RESOLVER} ||= '8.8.8.8';
1010

@@ -1092,3 +1092,315 @@ Hello, 2
10921092
***
10931093
--- no_error_log
10941094
[error]
1095+
1096+
1097+
1098+
=== TEST 28: coroutine.wrap propagates errors to parent coroutine
1099+
--- stream_server_config
1100+
content_by_lua_block {
1101+
local co = coroutine.wrap(function()
1102+
print("in wrapped coroutine")
1103+
error("something went wrong")
1104+
end)
1105+
1106+
co()
1107+
1108+
ngx.say("ok")
1109+
}
1110+
--- stream_response
1111+
--- error_log eval
1112+
[
1113+
qr/\[notice\] .*? in wrapped coroutine/,
1114+
qr/\[error\] .*? lua entry thread aborted: runtime error: content_by_lua\(nginx\.conf:\d+\):\d+: something went wrong/,
1115+
"stack traceback:",
1116+
"coroutine 0:",
1117+
"coroutine 1:"
1118+
]
1119+
1120+
1121+
1122+
=== TEST 29: coroutine.wrap propagates nested errors to parent coroutine
1123+
Note: in this case, both the error message and the traceback are constructed
1124+
from co1's stack level.
1125+
--- stream_server_config
1126+
content_by_lua_block {
1127+
local co1 = coroutine.wrap(function()
1128+
error("something went wrong in co1")
1129+
end)
1130+
1131+
local co2 = coroutine.wrap(function()
1132+
co1()
1133+
end)
1134+
1135+
co2()
1136+
}
1137+
--- stream_response
1138+
--- error_log eval
1139+
[
1140+
qr/\[error\] .*? lua entry thread aborted: runtime error: content_by_lua\(nginx\.conf:\d+\):\d+: something went wrong in co1/,
1141+
"stack traceback:",
1142+
"coroutine 0:",
1143+
"coroutine 1:",
1144+
"coroutine 2:"
1145+
]
1146+
1147+
1148+
1149+
=== TEST 30: coroutine.wrap propagates nested errors with stack level to parent coroutine
1150+
Note: in this case, the error message is constructed at the entry thread stack
1151+
level, and the traceback is constructed from co1's stack level.
1152+
--- stream_server_config
1153+
content_by_lua_block {
1154+
local co1 = coroutine.wrap(function()
1155+
error("something went wrong in co1", 2)
1156+
end)
1157+
1158+
local co2 = coroutine.wrap(function()
1159+
co1()
1160+
end)
1161+
1162+
co2()
1163+
}
1164+
--- stream_response
1165+
--- error_log eval
1166+
[
1167+
qr/\[error\] .*? lua entry thread aborted: runtime error: something went wrong in co1/,
1168+
"stack traceback:",
1169+
"coroutine 0:",
1170+
"coroutine 1:",
1171+
"coroutine 2:"
1172+
]
1173+
1174+
1175+
1176+
=== TEST 31: coroutine.wrap runtime errors do not log errors
1177+
--- stream_server_config
1178+
content_by_lua_block {
1179+
local co = coroutine.wrap(function()
1180+
print("in wrapped coroutine")
1181+
error("something went wrong")
1182+
end)
1183+
1184+
co()
1185+
}
1186+
--- stream_response
1187+
--- no_error_log eval
1188+
[
1189+
qr/\[error\] .*? lua coroutine: runtime error:/,
1190+
"[alert]",
1191+
"[crit]",
1192+
"[emerg]",
1193+
"[warn]",
1194+
]
1195+
1196+
1197+
1198+
=== TEST 32: coroutine.wrap does not return status boolean on yield
1199+
--- stream_server_config
1200+
content_by_lua_block {
1201+
local co = coroutine.wrap(function()
1202+
coroutine.yield("ok", "err")
1203+
end)
1204+
1205+
local ret1, ret2 = co()
1206+
1207+
ngx.say(ret1, ", ", ret2)
1208+
}
1209+
--- stream_response
1210+
ok, err
1211+
--- no_error_log
1212+
[error]
1213+
1214+
1215+
1216+
=== TEST 33: coroutine.wrap does not return status boolean on done
1217+
--- stream_server_config
1218+
content_by_lua_block {
1219+
local co = coroutine.wrap(function() end)
1220+
1221+
local ret1 = co()
1222+
1223+
ngx.say(ret1)
1224+
}
1225+
--- stream_response
1226+
nil
1227+
--- no_error_log
1228+
[emerg]
1229+
[alert]
1230+
[crit]
1231+
[error]
1232+
[warn]
1233+
1234+
1235+
1236+
=== TEST 34: coroutine.wrap does not return status boolean on error
1237+
--- SKIP: not supported
1238+
--- stream_server_config
1239+
content_by_lua_block {
1240+
local co = coroutine.wrap(function()
1241+
error("something went wrong")
1242+
end)
1243+
1244+
local ret1, ret2 = pcall(co)
1245+
1246+
ngx.say(ret1, ", ", ret2)
1247+
}
1248+
--- response_body
1249+
false, something went wrong
1250+
--- no_error_log
1251+
[error]
1252+
1253+
1254+
1255+
=== TEST 35: coroutine.wrap creates different function refs
1256+
--- stream_server_config
1257+
content_by_lua_block {
1258+
local f = function() end
1259+
local co = coroutine.wrap(f)
1260+
local co2 = coroutine.wrap(f)
1261+
1262+
ngx.say("co == co2: ", co == co2)
1263+
}
1264+
--- stream_response
1265+
co == co2: false
1266+
--- no_error_log
1267+
[emerg]
1268+
[alert]
1269+
[crit]
1270+
[error]
1271+
[warn]
1272+
1273+
1274+
1275+
=== TEST 36: coroutine.wrap supports yielding and resuming
1276+
--- stream_server_config
1277+
content_by_lua_block {
1278+
local function f()
1279+
local cnt = 0
1280+
for i = 1, 20 do
1281+
ngx.say("co yield: ", cnt)
1282+
coroutine.yield()
1283+
cnt = cnt + 1
1284+
end
1285+
end
1286+
1287+
local f = coroutine.wrap(f)
1288+
for i = 1, 3 do
1289+
ngx.say("co resume")
1290+
f()
1291+
end
1292+
}
1293+
--- stream_response
1294+
co resume
1295+
co yield: 0
1296+
co resume
1297+
co yield: 1
1298+
co resume
1299+
co yield: 2
1300+
--- no_error_log
1301+
[error]
1302+
1303+
1304+
1305+
=== TEST 37: coroutine.wrap return values
1306+
--- stream_server_config
1307+
content_by_lua_block {
1308+
local function f()
1309+
local cnt = 0
1310+
for i = 1, 20 do
1311+
coroutine.yield(cnt, cnt + 1)
1312+
cnt = cnt + 1
1313+
end
1314+
end
1315+
1316+
local f = coroutine.wrap(f)
1317+
for i = 1, 3 do
1318+
ngx.say("co resume")
1319+
local ret1, ret2 = f()
1320+
ngx.say("co yield: ", ret1, ", ", ret2)
1321+
end
1322+
}
1323+
--- stream_response
1324+
co resume
1325+
co yield: 0, 1
1326+
co resume
1327+
co yield: 1, 2
1328+
co resume
1329+
co yield: 2, 3
1330+
--- no_error_log
1331+
[error]
1332+
1333+
1334+
1335+
=== TEST 38: coroutine.wrap arguments
1336+
--- stream_server_config
1337+
content_by_lua_block {
1338+
local function f(step)
1339+
local cnt = 0
1340+
for i = 1, 20 do
1341+
ngx.say("co yield: ", cnt)
1342+
coroutine.yield()
1343+
cnt = cnt + step
1344+
end
1345+
end
1346+
1347+
local f = coroutine.wrap(f)
1348+
for i = 1, 3 do
1349+
ngx.say("co resume")
1350+
f(i)
1351+
end
1352+
}
1353+
--- stream_response
1354+
co resume
1355+
co yield: 0
1356+
co resume
1357+
co yield: 1
1358+
co resume
1359+
co yield: 2
1360+
--- no_error_log
1361+
[error]
1362+
1363+
1364+
1365+
=== TEST 39: coroutine.wrap in init_by_lua propagates errors (orig coroutine.wrap)
1366+
--- stream_config
1367+
init_by_lua_block {
1368+
local co = coroutine.wrap(function()
1369+
print("in wrapped coroutine")
1370+
error("something went wrong")
1371+
end)
1372+
1373+
local err = co()
1374+
1375+
ngx.log(ngx.CRIT, "err: ", err)
1376+
}
1377+
--- stream_server_config
1378+
content_by_lua_block {
1379+
ngx.say("ok")
1380+
}
1381+
--- must_die
1382+
--- grep_error_log eval: qr/init_by_lua error: .*? something went wrong/
1383+
--- grep_error_log_out
1384+
init_by_lua error: init_by_lua:7: init_by_lua:4: something went wrong
1385+
1386+
1387+
1388+
=== TEST 40: coroutine.resume runtime errors do not log errors
1389+
--- stream_server_config
1390+
content_by_lua_block {
1391+
local function f()
1392+
error("something went wrong")
1393+
end
1394+
1395+
local ret1, ret2 = coroutine.resume(coroutine.create(f))
1396+
ngx.say(ret1)
1397+
ngx.say(ret2)
1398+
}
1399+
--- stream_response_like
1400+
false
1401+
content_by_lua\(nginx.conf:\d+\):\d+: something went wrong
1402+
--- no_error_log eval
1403+
[
1404+
qr/\[error\] .*? lua coroutine: runtime error:",
1405+
"stack traceback:",
1406+
]

0 commit comments

Comments
 (0)