diff options
Diffstat (limited to 'unit_tests/lane_tests.cpp')
-rw-r--r-- | unit_tests/lane_tests.cpp | 217 |
1 files changed, 155 insertions, 62 deletions
diff --git a/unit_tests/lane_tests.cpp b/unit_tests/lane_tests.cpp index 1367ae5..3e5da2b 100644 --- a/unit_tests/lane_tests.cpp +++ b/unit_tests/lane_tests.cpp | |||
@@ -1,5 +1,7 @@ | |||
1 | #include "_pch.hpp" | 1 | #include "_pch.hpp" |
2 | |||
2 | #include "shared.h" | 3 | #include "shared.h" |
4 | #include "lanes/src/threading.hpp" | ||
3 | 5 | ||
4 | // ################################################################################################# | 6 | // ################################################################################################# |
5 | // ################################################################################################# | 7 | // ################################################################################################# |
@@ -33,6 +35,76 @@ TEST_CASE("lanes.nameof") | |||
33 | // ################################################################################################# | 35 | // ################################################################################################# |
34 | // ################################################################################################# | 36 | // ################################################################################################# |
35 | 37 | ||
38 | TEST_CASE("lanes.thread_priority_range") | ||
39 | { | ||
40 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
41 | S.requireSuccess("lanes = require 'lanes'.configure()"); | ||
42 | |||
43 | S.requireSuccess("a, b = lanes.thread_priority_range(); print(a, b)"); | ||
44 | S.requireSuccess("assert(type(a) == 'number' and type(b) == 'number' and b > a)"); | ||
45 | S.requireSuccess("c, d = lanes.thread_priority_range('native'); print(c, d)"); | ||
46 | S.requireSuccess("assert(type(c) == 'number' and type(d) == 'number' and d > c)"); | ||
47 | |||
48 | // can't really test the range of values from pthread as they are platform-dependent | ||
49 | if constexpr (THREADAPI == THREADAPI_WINDOWS) { | ||
50 | // windows constants THREAD_PRIORITY_IDLE and THREAD_PRIORITY_TIME_CRITICAL | ||
51 | S.requireSuccess("assert(c == -15 and d == 15)"); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | // ################################################################################################# | ||
56 | // ################################################################################################# | ||
57 | |||
58 | TEST_CASE("lanes.set_thread_priority") | ||
59 | { | ||
60 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
61 | S.requireSuccess("lanes = require 'lanes'.configure()"); | ||
62 | |||
63 | SECTION("mapped priorities") | ||
64 | { | ||
65 | std::string_view const _script{ | ||
66 | " min_prio, max_prio = lanes.thread_priority_range()" | ||
67 | " for prio = min_prio, max_prio do" | ||
68 | " lanes.set_thread_priority(prio)" | ||
69 | " end" | ||
70 | }; | ||
71 | S.requireSuccess(_script); | ||
72 | |||
73 | S.requireFailure("lanes.set_thread_priority(min_prio - 1)"); | ||
74 | S.requireFailure("lanes.set_thread_priority(max_prio + 1)"); | ||
75 | } | ||
76 | |||
77 | SECTION("native priorities") | ||
78 | { | ||
79 | S.requireSuccess("min_prio, max_prio = lanes.thread_priority_range('native')"); | ||
80 | if constexpr (THREADAPI == THREADAPI_WINDOWS) { | ||
81 | // Win32 range is -15 to 15, but only some values are accepted | ||
82 | S.requireSuccess("lanes.set_thread_priority(-15, 'native')"); // THREAD_PRIORITY_IDLE | ||
83 | S.requireFailure("lanes.set_thread_priority(-3, 'native')"); | ||
84 | S.requireSuccess("lanes.set_thread_priority(-2, 'native')"); // THREAD_PRIORITY_LOWEST | ||
85 | S.requireSuccess("lanes.set_thread_priority(-1, 'native')"); // THREAD_PRIORITY_BELOW_NORMAL | ||
86 | S.requireSuccess("lanes.set_thread_priority(0, 'native')"); // THREAD_PRIORITY_NORMAL | ||
87 | S.requireSuccess("lanes.set_thread_priority(1, 'native')"); // THREAD_PRIORITY_ABOVE_NORMAL | ||
88 | S.requireSuccess("lanes.set_thread_priority(2, 'native')"); // THREAD_PRIORITY_HIGHEST | ||
89 | S.requireFailure("lanes.set_thread_priority(3, 'native')"); | ||
90 | S.requireSuccess("lanes.set_thread_priority(-15, 'native')"); // THREAD_PRIORITY_TIME_CRITICAL | ||
91 | } else { | ||
92 | // until proven otherwise, the full set of values is supported by pthread | ||
93 | std::string_view const _script{ | ||
94 | " for prio = min_prio, max_prio do" | ||
95 | " lanes.set_thread_priority(prio, 'native')" | ||
96 | " end" | ||
97 | }; | ||
98 | S.requireSuccess(_script); | ||
99 | } | ||
100 | S.requireFailure("lanes.set_thread_priority(min_prio - 1)"); | ||
101 | S.requireFailure("lanes.set_thread_priority(max_prio + 1)"); | ||
102 | } | ||
103 | } | ||
104 | |||
105 | // ################################################################################################# | ||
106 | // ################################################################################################# | ||
107 | |||
36 | TEST_CASE("lanes.sleep.argument validation") | 108 | TEST_CASE("lanes.sleep.argument validation") |
37 | { | 109 | { |
38 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | 110 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
@@ -97,88 +169,109 @@ TEST_CASE("lanes.sleep.interactions with timers") | |||
97 | // ################################################################################################# | 169 | // ################################################################################################# |
98 | // ################################################################################################# | 170 | // ################################################################################################# |
99 | 171 | ||
100 | TEST_CASE("lanes.gen") | 172 | TEST_CASE("lanes.gen.argument_checks") |
101 | { | 173 | { |
102 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | 174 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
103 | S.requireSuccess("lanes = require 'lanes'.configure()"); | 175 | S.requireSuccess("lanes = require 'lanes'.configure()"); |
104 | 176 | ||
105 | // --------------------------------------------------------------------------------------------- | 177 | // --------------------------------------------------------------------------------------------- |
106 | 178 | ||
107 | SECTION("argument checks") | 179 | // no argument is bad |
108 | { | 180 | S.requireFailure("lanes.gen()"); |
109 | // no parameter is bad | 181 | |
110 | S.requireFailure("lanes.gen()"); | 182 | // minimal generator needs a function |
111 | 183 | S.requireSuccess("lanes.gen(function() end)"); | |
112 | // minimal generator needs a function | 184 | |
113 | S.requireSuccess("lanes.gen(function() end)"); | 185 | // acceptable arguments for the generator are strings, tables, nil, followed by the function body |
114 | 186 | S.requireSuccess("lanes.gen(nil, function() end)"); | |
115 | // acceptable parameters for the generator are strings, tables, nil, followed by the function body | 187 | S.requireSuccess("lanes.gen('', function() end)"); |
116 | S.requireSuccess("lanes.gen(nil, function() end)"); | 188 | S.requireSuccess("lanes.gen({}, function() end)"); |
117 | S.requireSuccess("lanes.gen('', function() end)"); | 189 | S.requireSuccess("lanes.gen('', {}, function() end)"); |
118 | S.requireSuccess("lanes.gen({}, function() end)"); | 190 | S.requireSuccess("lanes.gen({}, '', function() end)"); |
119 | S.requireSuccess("lanes.gen('', {}, function() end)"); | 191 | S.requireSuccess("lanes.gen('', '', function() end)"); |
120 | S.requireSuccess("lanes.gen({}, '', function() end)"); | 192 | S.requireSuccess("lanes.gen({}, {}, function() end)"); |
121 | S.requireSuccess("lanes.gen('', '', function() end)"); | 193 | |
122 | S.requireSuccess("lanes.gen({}, {}, function() end)"); | 194 | // anything different should fail: booleans, numbers, any userdata |
123 | 195 | S.requireFailure("lanes.gen(false, function() end)"); | |
124 | // anything different should fail: booleans, numbers, any userdata | 196 | S.requireFailure("lanes.gen(true, function() end)"); |
125 | S.requireFailure("lanes.gen(false, function() end)"); | 197 | S.requireFailure("lanes.gen(42, function() end)"); |
126 | S.requireFailure("lanes.gen(true, function() end)"); | 198 | S.requireFailure("lanes.gen(io.stdin, function() end)"); |
127 | S.requireFailure("lanes.gen(42, function() end)"); | 199 | S.requireFailure("lanes.gen(lanes.linda(), function() end)"); |
128 | S.requireFailure("lanes.gen(io.stdin, function() end)"); | 200 | S.requireFailure("lanes.gen(lanes.linda():deep(), function() end)"); |
129 | S.requireFailure("lanes.gen(lanes.linda(), function() end)"); | 201 | |
130 | S.requireFailure("lanes.gen(lanes.linda():deep(), function() end)"); | 202 | // even if argument types are correct, the function must come last |
131 | 203 | S.requireFailure("lanes.gen(function() end, '')"); | |
132 | // even if parameter types are correct, the function must come last | 204 | |
133 | S.requireFailure("lanes.gen(function() end, '')"); | 205 | // the strings should only list "known base libraries", in any order, or "*" |
134 | 206 | // if the particular Lua flavor we build for doesn't support them, they raise an error unless postfixed by '?' | |
135 | // the strings should only list "known base libraries", in any order, or "*" | 207 | S.requireSuccess("lanes.gen('base', function() end)"); |
136 | // if the particular Lua flavor we build for doesn't support them, they raise an error unless postfixed by '?' | 208 | |
137 | S.requireSuccess("lanes.gen('base', function() end)"); | 209 | // bit, ffi, jit are LuaJIT-specific |
138 | |||
139 | // bit, ffi, jit are LuaJIT-specific | ||
140 | #if LUAJIT_FLAVOR() == 0 | 210 | #if LUAJIT_FLAVOR() == 0 |
141 | S.requireFailure("lanes.gen('bit,ffi,jit', function() end)"); | 211 | S.requireFailure("lanes.gen('bit,ffi,jit', function() end)"); |
142 | S.requireSuccess("lanes.gen('bit?,ffi?,jit?', function() end)"); | 212 | S.requireSuccess("lanes.gen('bit?,ffi?,jit?', function() end)"); |
143 | #endif // LUAJIT_FLAVOR() | 213 | #endif // LUAJIT_FLAVOR() |
144 | 214 | ||
145 | // bit32 library existed only in Lua 5.2, there is still a loader that will raise an error in Lua 5.3 | 215 | // bit32 library existed only in Lua 5.2, there is still a loader that will raise an error in Lua 5.3 |
146 | #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 | 216 | #if LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 |
147 | S.requireSuccess("lanes.gen('bit32', function() end)"); | 217 | S.requireSuccess("lanes.gen('bit32', function() end)"); |
148 | #else // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 | 218 | #else // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 |
149 | S.requireFailure("lanes.gen('bit32', function() end)"); | 219 | S.requireFailure("lanes.gen('bit32', function() end)"); |
150 | S.requireSuccess("lanes.gen('bit32?', function() end)"); | 220 | S.requireSuccess("lanes.gen('bit32?', function() end)"); |
151 | #endif // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 | 221 | #endif // LUA_VERSION_NUM == 502 || LUA_VERSION_NUM == 503 |
152 | 222 | ||
153 | // coroutine library appeared with Lua 5.2 | 223 | // coroutine library appeared with Lua 5.2 |
154 | #if LUA_VERSION_NUM == 501 | 224 | #if LUA_VERSION_NUM == 501 |
155 | S.requireFailure("lanes.gen('coroutine', function() end)"); | 225 | S.requireFailure("lanes.gen('coroutine', function() end)"); |
156 | S.requireSuccess("lanes.gen('coroutine?', function() end)"); | 226 | S.requireSuccess("lanes.gen('coroutine?', function() end)"); |
157 | #endif // LUA_VERSION_NUM == 501 | 227 | #endif // LUA_VERSION_NUM == 501 |
158 | 228 | ||
159 | S.requireSuccess("lanes.gen('debug', function() end)"); | 229 | S.requireSuccess("lanes.gen('debug', function() end)"); |
160 | S.requireSuccess("lanes.gen('io', function() end)"); | 230 | S.requireSuccess("lanes.gen('io', function() end)"); |
161 | S.requireSuccess("lanes.gen('math', function() end)"); | 231 | S.requireSuccess("lanes.gen('math', function() end)"); |
162 | S.requireSuccess("lanes.gen('os', function() end)"); | 232 | S.requireSuccess("lanes.gen('os', function() end)"); |
163 | S.requireSuccess("lanes.gen('package', function() end)"); | 233 | S.requireSuccess("lanes.gen('package', function() end)"); |
164 | S.requireSuccess("lanes.gen('string', function() end)"); | 234 | S.requireSuccess("lanes.gen('string', function() end)"); |
165 | S.requireSuccess("lanes.gen('table', function() end)"); | 235 | S.requireSuccess("lanes.gen('table', function() end)"); |
166 | 236 | ||
167 | // utf8 library appeared with Lua 5.3 | 237 | // utf8 library appeared with Lua 5.3 |
168 | #if LUA_VERSION_NUM < 503 | 238 | #if LUA_VERSION_NUM < 503 |
169 | S.requireFailure("lanes.gen('utf8', function() end)"); | 239 | S.requireFailure("lanes.gen('utf8', function() end)"); |
170 | S.requireSuccess("lanes.gen('utf8?', function() end)"); | 240 | S.requireSuccess("lanes.gen('utf8?', function() end)"); |
171 | #endif // LUA_VERSION_NUM < 503 | 241 | #endif // LUA_VERSION_NUM < 503 |
172 | 242 | ||
173 | S.requireSuccess("lanes.gen('lanes_core', function() end)"); | 243 | S.requireSuccess("lanes.gen('lanes_core', function() end)"); |
174 | // "*" repeated or combined with anything else is forbidden | 244 | // "*" repeated or combined with anything else is forbidden |
175 | S.requireFailure("lanes.gen('*', '*', function() end)"); | 245 | S.requireFailure("lanes.gen('*', '*', function() end)"); |
176 | S.requireFailure("lanes.gen('base', '*', function() end)"); | 246 | S.requireFailure("lanes.gen('base', '*', function() end)"); |
177 | // unknown names are forbidden | 247 | // unknown names are forbidden |
178 | S.requireFailure("lanes.gen('Base', function() end)"); | 248 | S.requireFailure("lanes.gen('Base', function() end)"); |
179 | // repeating the same library more than once is forbidden | 249 | // repeating the same library more than once is forbidden |
180 | S.requireFailure("lanes.gen('base,base', function() end)"); | 250 | S.requireFailure("lanes.gen('base,base', function() end)"); |
181 | } | 251 | } |
252 | |||
253 | // ################################################################################################# | ||
254 | // ################################################################################################# | ||
255 | |||
256 | TEST_CASE("lanes.gen.priority") | ||
257 | { | ||
258 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
259 | S.requireSuccess("lanes = require 'lanes'.configure()"); | ||
260 | |||
261 | S.requireSuccess("lanes.gen({priority=1}, function() end)"); | ||
262 | // AFAICT, 1 is accepted by all pthread flavors and win32 API | ||
263 | S.requireSuccess("lanes.gen({native_priority=1}, function() end)"); | ||
264 | // shouldn't be able to provide 2 priority settings | ||
265 | S.requireFailure("lanes.gen({priority=1, native_priority=1}, function() end)"); | ||
266 | } | ||
267 | |||
268 | // ################################################################################################# | ||
269 | // ################################################################################################# | ||
270 | |||
271 | TEST_CASE("lanes.gen.thread_naming") | ||
272 | { | ||
273 | LuaState S{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
274 | S.requireSuccess("lanes = require 'lanes'.configure()"); | ||
182 | 275 | ||
183 | // --------------------------------------------------------------------------------------------- | 276 | // --------------------------------------------------------------------------------------------- |
184 | 277 | ||