|
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