diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2025-03-17 14:54:56 +0100 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2025-03-17 14:54:56 +0100 |
| commit | 7acc7867a8ebee0a3467a382b6998cb4e95580ed (patch) | |
| tree | 13f55245154b235b6a207e416d712702869644a0 /unit_tests | |
| parent | a57690123ae3ce5bdd7e970690f1380e88e4eaf6 (diff) | |
| download | lanes-7acc7867a8ebee0a3467a382b6998cb4e95580ed.tar.gz lanes-7acc7867a8ebee0a3467a382b6998cb4e95580ed.tar.bz2 lanes-7acc7867a8ebee0a3467a382b6998cb4e95580ed.zip | |
Fix test "allocator = <bad C function>" not failing against LuaJIT like it should
Diffstat (limited to 'unit_tests')
| -rw-r--r-- | unit_tests/init_and_shutdown.cpp | 347 |
1 files changed, 178 insertions, 169 deletions
diff --git a/unit_tests/init_and_shutdown.cpp b/unit_tests/init_and_shutdown.cpp index 9652f2d..b8174fd 100644 --- a/unit_tests/init_and_shutdown.cpp +++ b/unit_tests/init_and_shutdown.cpp | |||
| @@ -56,234 +56,243 @@ TEST_CASE("lanes.require 'lanes'") | |||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | // ################################################################################################# | 58 | // ################################################################################################# |
| 59 | // ################################################################################################# | ||
| 60 | // allocator should be "protected", a C function returning a suitable userdata, or nil | ||
| 61 | 59 | ||
| 62 | TEST_CASE("lanes.configure") | 60 | // allocator should be "protected", a C function returning a suitable userdata, or nil |
| 61 | TEST_CASE("lanes.configure.allocator") | ||
| 63 | { | 62 | { |
| 64 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | 63 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
| 65 | 64 | ||
| 65 | SECTION("allocator = false") | ||
| 66 | { | ||
| 67 | L.requireFailure("require 'lanes'.configure{allocator = false}"); | ||
| 68 | } | ||
| 69 | |||
| 66 | // --------------------------------------------------------------------------------------------- | 70 | // --------------------------------------------------------------------------------------------- |
| 67 | 71 | ||
| 68 | SECTION("allocator", "[allocator]") | 72 | SECTION("allocator = true") |
| 69 | { | 73 | { |
| 70 | SECTION("allocator = false") | 74 | L.requireFailure("require 'lanes'.configure{allocator = true}"); |
| 71 | { | 75 | } |
| 72 | L.requireFailure("require 'lanes'.configure{allocator = false}"); | ||
| 73 | } | ||
| 74 | 76 | ||
| 75 | // ----------------------------------------------------------------------------------------- | 77 | // --------------------------------------------------------------------------------------------- |
| 76 | 78 | ||
| 77 | SECTION("allocator = true") | 79 | SECTION("allocator = <number>") |
| 78 | { | 80 | { |
| 79 | L.requireFailure("require 'lanes'.configure{allocator = true}"); | 81 | L.requireFailure("require 'lanes'.configure{allocator = 33}"); |
| 80 | } | 82 | } |
| 81 | 83 | ||
| 82 | // ----------------------------------------------------------------------------------------- | 84 | // --------------------------------------------------------------------------------------------- |
| 83 | 85 | ||
| 84 | SECTION("allocator = <number>") | 86 | SECTION("allocator = <table>") |
| 85 | { | 87 | { |
| 86 | L.requireFailure("require 'lanes'.configure{allocator = 33}"); | 88 | L.requireFailure("require 'lanes'.configure{allocator = {}}"); |
| 87 | } | 89 | } |
| 88 | 90 | ||
| 89 | // ----------------------------------------------------------------------------------------- | 91 | // --------------------------------------------------------------------------------------------- |
| 90 | 92 | ||
| 91 | SECTION("allocator = <table>") | 93 | SECTION("allocator = <Lua function>") |
| 92 | { | 94 | { |
| 93 | L.requireFailure("require 'lanes'.configure{allocator = {}}"); | 95 | L.requireFailure("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}"); |
| 94 | } | 96 | } |
| 95 | 97 | ||
| 96 | // ----------------------------------------------------------------------------------------- | 98 | // --------------------------------------------------------------------------------------------- |
| 97 | 99 | ||
| 98 | SECTION("allocator = <Lua function>") | 100 | SECTION("allocator = <bad C function>") |
| 99 | { | 101 | { |
| 100 | L.requireFailure("require 'lanes'.configure{allocator = function() return {}, 12, 'yoy' end}"); | 102 | // a C function that doesn't return what we expect should cause an error too |
| 101 | } | 103 | // TODO: for some reason, we use os.getenv here because using 'print' as the culprit, the tests deadlock in Release builds |
| 104 | L.requireFailure("return type(require 'lanes'.configure{allocator = os.getenv})"); | ||
| 105 | } | ||
| 102 | 106 | ||
| 103 | // ----------------------------------------------------------------------------------------- | 107 | // --------------------------------------------------------------------------------------------- |
| 104 | 108 | ||
| 105 | SECTION("allocator = <bad C function>") | 109 | SECTION("allocator = <string with a typo>") |
| 106 | { | 110 | { |
| 107 | // a C function that doesn't return what we expect should cause an error too | 111 | // oops, a typo |
| 108 | L.requireFailure("require 'lanes'.configure{allocator = print}"); | 112 | L.requireFailure("require 'lanes'.configure{allocator = 'Protected'}"); |
| 109 | } | 113 | } |
| 110 | 114 | ||
| 111 | // ----------------------------------------------------------------------------------------- | 115 | // --------------------------------------------------------------------------------------------- |
| 112 | 116 | ||
| 113 | SECTION("allocator = <string with a typo>") | 117 | SECTION("allocator = 'protected'") |
| 114 | { | 118 | { |
| 115 | // oops, a typo | 119 | // no typo, should work |
| 116 | L.requireFailure("require 'lanes'.configure{allocator = 'Protected'}"); | 120 | L.requireSuccess("require 'lanes'.configure{allocator = 'protected'}"); |
| 117 | } | 121 | } |
| 118 | 122 | ||
| 119 | // ----------------------------------------------------------------------------------------- | 123 | // --------------------------------------------------------------------------------------------- |
| 120 | 124 | ||
| 121 | SECTION("allocator = 'protected'") | 125 | SECTION("allocator = <good custom C allocator>") |
| 122 | { | 126 | { |
| 123 | // no typo, should work | 127 | // a function that provides what we expect is fine |
| 124 | L.requireSuccess("require 'lanes'.configure{allocator = 'protected'}"); | 128 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
| 125 | } | 129 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; |
| 130 | _def->initFrom(L_); | ||
| 131 | return 1; | ||
| 132 | }; | ||
| 133 | lua_pushcfunction(L, _provideAllocator); | ||
| 134 | lua_setglobal(L, "ProvideAllocator"); | ||
| 135 | L.requireSuccess("require 'lanes'.configure{allocator = ProvideAllocator}"); | ||
| 136 | } | ||
| 126 | 137 | ||
| 127 | // ----------------------------------------------------------------------------------------- | 138 | // --------------------------------------------------------------------------------------------- |
| 128 | 139 | ||
| 129 | SECTION("allocator = <good custom C allocator>") | 140 | SECTION("allocator not returning an AllocatorDefinition") |
| 130 | { | 141 | { |
| 131 | // a function that provides what we expect is fine | 142 | // a function that provides something that is definitely not an AllocatorDefinition, should cause an error |
| 132 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 143 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
| 133 | lanes::AllocatorDefinition* const _def{ new (L_) lanes::AllocatorDefinition{} }; | 144 | lua_newtable(L_); |
| 134 | _def->initFrom(L_); | 145 | return 1; |
| 135 | return 1; | 146 | }; |
| 136 | }; | 147 | lua_pushcfunction(L, _provideAllocator); |
| 137 | lua_pushcfunction(L, _provideAllocator); | 148 | lua_setglobal(L, "ProvideAllocator"); |
| 138 | lua_setglobal(L, "ProvideAllocator"); | 149 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected |
| 139 | L.requireSuccess("require 'lanes'.configure{allocator = ProvideAllocator}"); | 150 | // which would prevent us from calling _provideAllocator |
| 140 | } | 151 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); |
| 152 | } | ||
| 141 | 153 | ||
| 142 | // ----------------------------------------------------------------------------------------- | 154 | // --------------------------------------------------------------------------------------------- |
| 143 | 155 | ||
| 144 | SECTION("allocator not returning an AllocatorDefinition") | 156 | SECTION("allocator returning an AllocatorDefinition with the wrong signature") |
| 145 | { | 157 | { |
| 146 | // a function that provides something that is definitely not an AllocatorDefinition, should cause an error | 158 | // a function that provides something that is too small to contain an AllocatorDefinition, should cause an error |
| 147 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 159 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
| 148 | lua_newtable(L_); | 160 | // create a full userdata that is too small (it only contains enough to store a version tag, but not the rest |
| 149 | return 1; | 161 | auto* const _duck{ static_cast<lanes::AllocatorDefinition::version_t*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition::version_t))) }; |
| 150 | }; | 162 | *_duck = 666777; |
| 151 | lua_pushcfunction(L, _provideAllocator); | 163 | return 1; |
| 152 | lua_setglobal(L, "ProvideAllocator"); | 164 | }; |
| 153 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected | 165 | lua_pushcfunction(L, _provideAllocator); |
| 154 | // which would prevent us from calling _provideAllocator | 166 | lua_setglobal(L, "ProvideAllocator"); |
| 155 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); | 167 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected |
| 156 | } | 168 | // which would prevent us from calling _provideAllocator |
| 169 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); | ||
| 170 | } | ||
| 157 | 171 | ||
| 158 | // ----------------------------------------------------------------------------------------- | 172 | // ----------------------------------------------------------------------------------------- |
| 159 | 173 | ||
| 160 | SECTION("allocator returning an AllocatorDefinition with the wrong signature") | 174 | SECTION("allocator returning something too small to be a valid AllocatorDefinition") |
| 161 | { | 175 | { |
| 162 | // a function that provides something that is too small to contain an AllocatorDefinition, should cause an error | 176 | // a function that provides something that attempts to pass as an AllocatorDefinition, but is not, should cause an error |
| 163 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | 177 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { |
| 164 | // create a full userdata that is too small (it only contains enough to store a version tag, but not the rest | 178 | // create a full userdata of the correct size, but of course the contents don't match |
| 165 | auto* const _duck{ static_cast<lanes::AllocatorDefinition::version_t*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition::version_t))) }; | 179 | int* const _duck{ static_cast<int*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition))) }; |
| 166 | *_duck = 666777; | 180 | _duck[0] = 666; |
| 167 | return 1; | 181 | _duck[1] = 777; |
| 168 | }; | 182 | return 1; |
| 169 | lua_pushcfunction(L, _provideAllocator); | 183 | }; |
| 170 | lua_setglobal(L, "ProvideAllocator"); | 184 | lua_pushcfunction(L, _provideAllocator); |
| 171 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected | 185 | lua_setglobal(L, "ProvideAllocator"); |
| 172 | // which would prevent us from calling _provideAllocator | 186 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected |
| 173 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); | 187 | // which would prevent us from calling _provideAllocator |
| 174 | } | 188 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); |
| 189 | } | ||
| 190 | } | ||
| 175 | 191 | ||
| 176 | // ----------------------------------------------------------------------------------------- | 192 | // ################################################################################################# |
| 177 | 193 | ||
| 178 | SECTION("allocator returning something too small to be a valid AllocatorDefinition") | 194 | TEST_CASE("lanes.configure.internal_allocator") |
| 179 | { | 195 | { |
| 180 | // a function that provides something that attempts to pass as an AllocatorDefinition, but is not, should cause an error | 196 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; |
| 181 | static constexpr lua_CFunction _provideAllocator = +[](lua_State* const L_) { | ||
| 182 | // create a full userdata of the correct size, but of course the contents don't match | ||
| 183 | int* const _duck{ static_cast<int*>(lua_newuserdata(L_, sizeof(lanes::AllocatorDefinition))) }; | ||
| 184 | _duck[0] = 666; | ||
| 185 | _duck[1] = 777; | ||
| 186 | return 1; | ||
| 187 | }; | ||
| 188 | lua_pushcfunction(L, _provideAllocator); | ||
| 189 | lua_setglobal(L, "ProvideAllocator"); | ||
| 190 | // force value of internal_allocator so that the LuaJIT-default 'libc' is not selected | ||
| 191 | // which would prevent us from calling _provideAllocator | ||
| 192 | L.requireFailure("require 'lanes'.configure{allocator = ProvideAllocator, internal_allocator = 'allocator'}"); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | 197 | ||
| 196 | // --------------------------------------------------------------------------------------------- | ||
| 197 | // internal_allocator should be a string, "libc"/"allocator" | 198 | // internal_allocator should be a string, "libc"/"allocator" |
| 198 | 199 | ||
| 199 | SECTION("[internal_allocator") | 200 | SECTION("internal_allocator = false") |
| 200 | { | 201 | { |
| 201 | SECTION("internal_allocator = false") | 202 | L.requireFailure("require 'lanes'.configure{internal_allocator = false}"); |
| 202 | { | 203 | } |
| 203 | L.requireFailure("require 'lanes'.configure{internal_allocator = false}"); | ||
| 204 | } | ||
| 205 | 204 | ||
| 206 | // ----------------------------------------------------------------------------------------- | 205 | // --------------------------------------------------------------------------------------------- |
| 207 | 206 | ||
| 208 | SECTION("internal_allocator = true") | 207 | SECTION("internal_allocator = true") |
| 209 | { | 208 | { |
| 210 | L.requireFailure("require 'lanes'.configure{internal_allocator = true}"); | 209 | L.requireFailure("require 'lanes'.configure{internal_allocator = true}"); |
| 211 | } | 210 | } |
| 212 | 211 | ||
| 213 | // ----------------------------------------------------------------------------------------- | 212 | // --------------------------------------------------------------------------------------------- |
| 214 | 213 | ||
| 215 | SECTION("internal_allocator = <table>") | 214 | SECTION("internal_allocator = <table>") |
| 216 | { | 215 | { |
| 217 | L.requireFailure("require 'lanes'.configure{internal_allocator = {}}"); | 216 | L.requireFailure("require 'lanes'.configure{internal_allocator = {}}"); |
| 218 | } | 217 | } |
| 219 | 218 | ||
| 220 | // ----------------------------------------------------------------------------------------- | 219 | // --------------------------------------------------------------------------------------------- |
| 221 | 220 | ||
| 222 | SECTION("internal_allocator = <Lua function>") | 221 | SECTION("internal_allocator = <Lua function>") |
| 223 | { | 222 | { |
| 224 | L.requireFailure("require 'lanes'.configure{internal_allocator = function() end}"); | 223 | L.requireFailure("require 'lanes'.configure{internal_allocator = function() end}"); |
| 225 | } | 224 | } |
| 226 | 225 | ||
| 227 | // ----------------------------------------------------------------------------------------- | 226 | // --------------------------------------------------------------------------------------------- |
| 228 | 227 | ||
| 229 | SECTION("internal_allocator = <bad string>") | 228 | SECTION("internal_allocator = <bad string>") |
| 230 | { | 229 | { |
| 231 | L.requireFailure("require 'lanes'.configure{internal_allocator = 'gluh'}"); | 230 | L.requireFailure("require 'lanes'.configure{internal_allocator = 'gluh'}"); |
| 232 | } | 231 | } |
| 233 | 232 | ||
| 234 | // ----------------------------------------------------------------------------------------- | 233 | // --------------------------------------------------------------------------------------------- |
| 235 | 234 | ||
| 236 | SECTION("internal_allocator = 'libc'") | 235 | SECTION("internal_allocator = 'libc'") |
| 237 | { | 236 | { |
| 238 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'libc'}"); | 237 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'libc'}"); |
| 239 | } | 238 | } |
| 240 | 239 | ||
| 241 | // ----------------------------------------------------------------------------------------- | 240 | // --------------------------------------------------------------------------------------------- |
| 242 | 241 | ||
| 243 | SECTION("internal_allocator = 'allocator'") | 242 | SECTION("internal_allocator = 'allocator'") |
| 244 | { | 243 | { |
| 245 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'allocator'}"); | 244 | L.requireSuccess("require 'lanes'.configure{internal_allocator = 'allocator'}"); |
| 246 | } | ||
| 247 | } | 245 | } |
| 246 | } | ||
| 247 | |||
| 248 | // ################################################################################################# | ||
| 249 | |||
| 250 | TEST_CASE("lanes.configure.keepers_gc_threshold") | ||
| 251 | { | ||
| 252 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
| 248 | 253 | ||
| 249 | // --------------------------------------------------------------------------------------------- | ||
| 250 | // keepers_gc_threshold should be a number in [0, 100] | 254 | // keepers_gc_threshold should be a number in [0, 100] |
| 251 | 255 | ||
| 252 | SECTION("keepers_gc_threshold") | 256 | SECTION("keepers_gc_threshold = <table>") |
| 253 | { | 257 | { |
| 254 | SECTION("keepers_gc_threshold = <table>") | 258 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = {}}"); |
| 255 | { | 259 | } |
| 256 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = {}}"); | ||
| 257 | } | ||
| 258 | 260 | ||
| 259 | // ----------------------------------------------------------------------------------------- | 261 | // --------------------------------------------------------------------------------------------- |
| 260 | 262 | ||
| 261 | SECTION("keepers_gc_threshold = <string>") | 263 | SECTION("keepers_gc_threshold = <string>") |
| 262 | { | 264 | { |
| 263 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = 'gluh'}"); | 265 | L.requireFailure("require 'lanes'.configure{keepers_gc_threshold = 'gluh'}"); |
| 264 | } | 266 | } |
| 265 | 267 | ||
| 266 | // ----------------------------------------------------------------------------------------- | 268 | // --------------------------------------------------------------------------------------------- |
| 267 | 269 | ||
| 268 | SECTION("keepers_gc_threshold = -1") | 270 | SECTION("keepers_gc_threshold = -1") |
| 269 | { | 271 | { |
| 270 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = -1}"); | 272 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = -1}"); |
| 271 | } | 273 | } |
| 272 | 274 | ||
| 273 | // ----------------------------------------------------------------------------------------- | 275 | // --------------------------------------------------------------------------------------------- |
| 274 | 276 | ||
| 275 | SECTION("keepers_gc_threshold = 0") | 277 | SECTION("keepers_gc_threshold = 0") |
| 276 | { | 278 | { |
| 277 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 0}"); | 279 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 0}"); |
| 278 | } | 280 | } |
| 279 | 281 | ||
| 280 | // ----------------------------------------------------------------------------------------- | 282 | // --------------------------------------------------------------------------------------------- |
| 281 | 283 | ||
| 282 | SECTION("keepers_gc_threshold = 100") | 284 | SECTION("keepers_gc_threshold = 100") |
| 283 | { | 285 | { |
| 284 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 100}"); | 286 | L.requireSuccess("require 'lanes'.configure{keepers_gc_threshold = 100}"); |
| 285 | } | ||
| 286 | } | 287 | } |
| 288 | } | ||
| 289 | |||
| 290 | // ################################################################################################# | ||
| 291 | |||
| 292 | TEST_CASE("lanes.configure.the rest") | ||
| 293 | { | ||
| 294 | LuaState L{ LuaState::WithBaseLibs{ true }, LuaState::WithFixture{ false } }; | ||
| 295 | |||
| 287 | 296 | ||
| 288 | // --------------------------------------------------------------------------------------------- | 297 | // --------------------------------------------------------------------------------------------- |
| 289 | // nb_user_keepers should be a number in [0, 100] | 298 | // nb_user_keepers should be a number in [0, 100] |
