|
28 | 28 | #include <umf/providers/provider_os_memory.h> |
29 | 29 |
|
30 | 30 | #include "../common/base.hpp" |
| 31 | +#include "../common/fork_helpers.hpp" |
31 | 32 | #include "gtest/gtest.h" |
32 | 33 |
|
33 | 34 | using namespace umf_test; |
@@ -184,20 +185,21 @@ class CtlTest : public ::testing::Test { |
184 | 185 | private: |
185 | 186 | }; |
186 | 187 |
|
187 | | -/* Case: default settings |
188 | | - * This test sets a default value and then retrieves it */ |
| 188 | +// setting default modyfies global state - |
| 189 | +// tests doing so should run in fork to ensure correct test isolation |
189 | 190 | TEST_F(CtlTest, ctlDefault) { |
190 | | - const char *arg = "default_name"; |
191 | | - |
192 | | - auto res = umfCtlSet("umf.pool.default.some_pool.some_path", (void *)arg, |
193 | | - strlen(arg)); |
194 | | - ASSERT_EQ(res, UMF_RESULT_SUCCESS); |
195 | | - |
196 | | - char output[64] = {1}; |
197 | | - res = umfCtlGet("umf.pool.default.some_pool.some_path", (void *)output, |
198 | | - sizeof(output)); |
199 | | - ASSERT_EQ(res, UMF_RESULT_SUCCESS); |
200 | | - ASSERT_STREQ(output, arg); |
| 191 | + umf_test::run_in_fork([] { |
| 192 | + const char *arg = "default_name"; |
| 193 | + ASSERT_EQ(umfCtlSet("umf.pool.default.some_pool.some_path", |
| 194 | + (void *)arg, strlen(arg)), |
| 195 | + UMF_RESULT_SUCCESS); |
| 196 | + |
| 197 | + char output[64] = {1}; |
| 198 | + ASSERT_EQ(umfCtlGet("umf.pool.default.some_pool.some_path", |
| 199 | + (void *)output, sizeof(output)), |
| 200 | + UMF_RESULT_SUCCESS); |
| 201 | + ASSERT_STREQ(output, arg); |
| 202 | + }); |
201 | 203 | } |
202 | 204 |
|
203 | 205 | /* Case: umfCtlSet negative test */ |
@@ -234,58 +236,64 @@ TEST_F(CtlTest, ctlGetInvalid) { |
234 | 236 | /* Case: multi-threaded test for pool defaults |
235 | 237 | * This test sets a default value in multiple threads and then retrieves it */ |
236 | 238 | TEST_F(CtlTest, ctlDefaultPoolMultithreaded) { |
237 | | - const size_t max_size = 10; |
238 | | - const size_t num_threads = 8; |
239 | | - std::vector<std::thread> threads; |
240 | | - std::atomic<size_t> totalRecords = 0; |
241 | | - const char *predefined_value = "xyzzyx"; |
242 | | - std::string name_prefix = "umf.pool.default.some_pool."; |
243 | | - for (size_t i = 0; i < num_threads; i++) { |
244 | | - threads.emplace_back([i, &totalRecords, &predefined_value, &name_prefix, |
245 | | - max_size = max_size]() { |
246 | | - for (size_t j = 0; j < max_size; j++) { |
247 | | - std::string name = name_prefix + std::to_string(i * 10 + j); |
248 | | - umfCtlSet(name.c_str(), (void *)predefined_value, |
249 | | - strlen(predefined_value)); |
250 | | - std::atomic_fetch_add(&totalRecords, 1UL); |
251 | | - } |
252 | | - }); |
253 | | - } |
254 | | - for (auto &thread : threads) { |
255 | | - thread.join(); |
256 | | - } |
| 239 | + umf_test::run_in_fork([] { |
| 240 | + const size_t max_size = 10; |
| 241 | + const size_t num_threads = 8; |
| 242 | + std::vector<std::thread> threads; |
| 243 | + std::atomic<size_t> totalRecords = 0; |
| 244 | + const char *predefined_value = "xyzzyx"; |
| 245 | + std::string name_prefix = "umf.pool.default.some_pool."; |
| 246 | + for (size_t i = 0; i < num_threads; i++) { |
| 247 | + threads.emplace_back([i, &totalRecords, &predefined_value, |
| 248 | + &name_prefix, max_size = max_size]() { |
| 249 | + for (size_t j = 0; j < max_size; j++) { |
| 250 | + std::string name = |
| 251 | + name_prefix + std::to_string(i * 10 + j); |
| 252 | + umfCtlSet(name.c_str(), (void *)predefined_value, |
| 253 | + strlen(predefined_value)); |
| 254 | + std::atomic_fetch_add(&totalRecords, 1UL); |
| 255 | + } |
| 256 | + }); |
| 257 | + } |
| 258 | + for (auto &thread : threads) { |
| 259 | + thread.join(); |
| 260 | + } |
257 | 261 |
|
258 | | - // Check if all threads set the value correctly |
259 | | - // and retrieve it |
260 | | - ASSERT_EQ(totalRecords.load(), num_threads * max_size); |
| 262 | + ASSERT_EQ(totalRecords.load(), num_threads * max_size); |
261 | 263 |
|
262 | | - char output[100] = {0}; |
263 | | - for (size_t i = 0; i < totalRecords.load(); i++) { |
264 | | - std::string name = name_prefix + std::to_string(i); |
265 | | - auto status = umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
266 | | - ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
267 | | - ASSERT_EQ(std::string(output), std::string(predefined_value)); |
268 | | - } |
| 264 | + char output[100] = {0}; |
| 265 | + for (size_t i = 0; i < totalRecords.load(); i++) { |
| 266 | + std::string name = name_prefix + std::to_string(i); |
| 267 | + umf_result_t status = |
| 268 | + umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
| 269 | + ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
| 270 | + ASSERT_STREQ(output, predefined_value); |
| 271 | + } |
| 272 | + }); |
269 | 273 | } |
270 | 274 |
|
271 | 275 | /* Case: overwriting an existing value for pool defaults |
272 | 276 | * This test sets a default value and then overwrites it with a new value */ |
273 | 277 | TEST_F(CtlTest, ctlDefaultPoolOverwrite) { |
274 | | - constexpr int max_size = 10; |
275 | | - std::vector<std::string> values; |
276 | | - const std::string name = "umf.pool.default.some_pool"; |
277 | | - |
278 | | - for (int i = 0; i < max_size; i++) { |
279 | | - values.push_back("value_" + std::to_string(i)); |
280 | | - umfCtlSet(name.c_str(), (void *)values.back().c_str(), |
281 | | - values.back().size()); |
282 | | - } |
| 278 | + umf_test::run_in_fork([] { |
| 279 | + constexpr int max_size = 10; |
| 280 | + std::vector<std::string> values; |
| 281 | + const std::string name = "umf.pool.default.some_pool"; |
| 282 | + |
| 283 | + for (int i = 0; i < max_size; i++) { |
| 284 | + values.push_back("value_" + std::to_string(i)); |
| 285 | + umf_result_t set_status = |
| 286 | + umfCtlSet(name.c_str(), (void *)values.back().c_str(), |
| 287 | + values.back().size()); |
| 288 | + ASSERT_EQ(set_status, UMF_RESULT_SUCCESS); |
| 289 | + } |
283 | 290 |
|
284 | | - char output[100] = {0}; |
285 | | - umf_result_t status = |
286 | | - umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
287 | | - ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
288 | | - ASSERT_EQ(std::string(output), values.back()); |
| 291 | + char output[100] = {0}; |
| 292 | + umf_result_t status = |
| 293 | + umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
| 294 | + ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
| 295 | + ASSERT_STREQ(output, values.back().c_str()); |
| 296 | + }); |
289 | 297 | } |
290 | 298 |
|
291 | 299 | TEST_F(CtlTest, DISABLED_ctlNameValidation) { |
@@ -349,32 +357,36 @@ TEST_F(CtlTest, DISABLED_ctlExecInvalidSize) { |
349 | 357 | } |
350 | 358 |
|
351 | 359 | TEST_F(CtlTest, ctlDefaultMultithreadedProvider) { |
352 | | - std::vector<std::thread> threads; |
353 | | - std::atomic<size_t> totalRecords = 0; |
354 | | - const char *predefined_value = "xyzzyx"; |
355 | | - std::string name_prefix = "umf.provider.default.some_provider."; |
356 | | - for (int i = 0; i < 8; i++) { |
357 | | - threads.emplace_back( |
358 | | - [i, &totalRecords, &predefined_value, &name_prefix]() { |
359 | | - for (int j = 0; j < 10; j++) { |
360 | | - std::string name = name_prefix + std::to_string(i * 10 + j); |
361 | | - umfCtlSet(name.c_str(), (void *)predefined_value, |
362 | | - strlen(predefined_value)); |
363 | | - std::atomic_fetch_add(&totalRecords, 1); |
364 | | - } |
365 | | - }); |
366 | | - } |
367 | | - for (auto &thread : threads) { |
368 | | - thread.join(); |
369 | | - } |
| 360 | + umf_test::run_in_fork([] { |
| 361 | + std::vector<std::thread> threads; |
| 362 | + std::atomic<size_t> totalRecords = 0; |
| 363 | + const char *predefined_value = "xyzzyx"; |
| 364 | + std::string name_prefix = "umf.provider.default.some_provider."; |
| 365 | + for (int i = 0; i < 8; i++) { |
| 366 | + threads.emplace_back( |
| 367 | + [i, &totalRecords, &predefined_value, &name_prefix]() { |
| 368 | + for (int j = 0; j < 10; j++) { |
| 369 | + std::string name = |
| 370 | + name_prefix + std::to_string(i * 10 + j); |
| 371 | + umfCtlSet(name.c_str(), (void *)predefined_value, |
| 372 | + strlen(predefined_value)); |
| 373 | + std::atomic_fetch_add(&totalRecords, 1); |
| 374 | + } |
| 375 | + }); |
| 376 | + } |
| 377 | + for (auto &thread : threads) { |
| 378 | + thread.join(); |
| 379 | + } |
370 | 380 |
|
371 | | - char output[100] = {0}; |
372 | | - for (size_t i = 0; i < totalRecords.load(); i++) { |
373 | | - std::string name = name_prefix + std::to_string(i); |
374 | | - auto status = umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
375 | | - ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
376 | | - ASSERT_EQ(std::string(output), std::string(predefined_value)); |
377 | | - } |
| 381 | + char output[100] = {0}; |
| 382 | + for (size_t i = 0; i < totalRecords.load(); i++) { |
| 383 | + std::string name = name_prefix + std::to_string(i); |
| 384 | + umf_result_t status = |
| 385 | + umfCtlGet(name.c_str(), (void *)output, sizeof(output)); |
| 386 | + ASSERT_EQ(status, UMF_RESULT_SUCCESS); |
| 387 | + ASSERT_STREQ(output, predefined_value); |
| 388 | + } |
| 389 | + }); |
378 | 390 | } |
379 | 391 |
|
380 | 392 | TEST_F(test, ctl_logger_basic_rw) { |
|
0 commit comments