diff --git a/.clang-format b/.clang-format index a392e039ca1..bfd879b27f2 100644 --- a/.clang-format +++ b/.clang-format @@ -149,6 +149,7 @@ ForEachMacros: - mlib_foreach_urange - mlib_foreach - mlib_foreach_arr + - mlib_vec_foreach IfMacros: - mlib_assert_aborts - KJ_IF_MAYBE diff --git a/CMakeLists.txt b/CMakeLists.txt index 634c26446fb..773f1ebb920 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,6 +292,7 @@ if(ENABLE_MAINTAINER_FLAGS) gnu-like:-Wuninitialized # Disabled, for now: gnu-like:-Wno-strict-aliasing + gnu-like:-Wno-missing-braces # Sign-comparison-mismatch: gnu-like:-Wsign-compare msvc:/we4018 diff --git a/Earthfile b/Earthfile index ba6af57c399..6ebb576e250 100644 --- a/Earthfile +++ b/Earthfile @@ -137,6 +137,7 @@ PREP_CMAKE: FUNCTION # Run all CMake commands using uvx: RUN __alias cmake uvx cmake + RUN __alias ctest uvx --from=cmake ctest # Executing any CMake command will warm the cache: RUN cmake --version | head -n 1 diff --git a/build/cmake/LoadTests.cmake b/build/cmake/LoadTests.cmake index 262797b4779..7aa9c4203bf 100644 --- a/build/cmake/LoadTests.cmake +++ b/build/cmake/LoadTests.cmake @@ -3,57 +3,88 @@ # allowing CTest to control the execution, parallelization, and collection of # test results. -if (NOT EXISTS "${TEST_LIBMONGOC_EXE}") +if(NOT EXISTS "${TEST_LIBMONGOC_EXE}") # This will fail if 'test-libmongoc' is not compiled yet. - message (WARNING "The test executable ${TEST_LIBMONGOC_EXE} is not present. " - "Its tests will not be registered") - add_test (mongoc/not-found NOT_FOUND) - return () -endif () - -# Get the list of tests -execute_process ( - COMMAND "${TEST_LIBMONGOC_EXE}" --list-tests --no-fork - OUTPUT_VARIABLE tests_out + message(WARNING "The test executable ${TEST_LIBMONGOC_EXE} is not present. " + "Its tests will not be registered") + add_test(mongoc/not-found NOT_FOUND) + return() +endif() + +# Get the list of tests. This command emits CMake code that defines variables for +# all test cases defined in the suite +execute_process( + COMMAND "${TEST_LIBMONGOC_EXE}" --tests-cmake --no-fork + OUTPUT_VARIABLE tests_cmake WORKING_DIRECTORY "${SRC_ROOT}" RESULT_VARIABLE retc ) -if (retc) +if(retc) # Failed to list the tests. That's bad. - message (FATAL_ERROR "Failed to run test-libmongoc to discover tests [${retc}]:\n${tests_out}") -endif () + message(FATAL_ERROR "Failed to run test-libmongoc to discover tests [${retc}]:\n${tests_out}") +endif() -# Split lines on newlines -string (REPLACE "\n" ";" lines "${tests_out}") +# Execute the code that defines the test case information +cmake_language(EVAL CODE "${tests_cmake}") -# TODO: Allow individual test cases to specify the fixtures they want. -set (all_fixtures "mongoc/fixtures/fake_kms_provider_server") -set (all_env +# Define environment variables that are common to all test cases +set(all_env TEST_KMS_PROVIDER_HOST=localhost:14987 # Refer: Fixtures.cmake ) -# Generate the test definitions -foreach (line IN LISTS lines) - if (NOT line MATCHES "^/") - # Only generate if the line begins with `/`, which all tests should. - continue () - endif () - # The new test name is prefixed with 'mongoc' - set (test "mongoc${line}") - # Define the test. Use `--ctest-run` to tell it that CTest is in control. - add_test ("${test}" "${TEST_LIBMONGOC_EXE}" --ctest-run "${line}") - set_tests_properties ("${test}" PROPERTIES +function(list_select list_var) + cmake_parse_arguments(PARSE_ARGV 1 arg "" "SELECT;REPLACE;OUT" "") + set(seq "${${list_var}}") + list(FILTER seq INCLUDE REGEX "${arg_SELECT}") + list(TRANSFORM seq REPLACE "${arg_SELECT}" "${arg_REPLACE}") + set("${arg_OUT}" "${seq}" PARENT_SCOPE) +endfunction() + +# The emitted code defines a list MONGOC_TESTS with the name of every test case +# in the suite. +foreach(casename IN LISTS MONGOC_TESTS) + set(name "mongoc${casename}") + # Run the program with --ctest-run to select only this one test case + add_test("${name}" "${TEST_LIBMONGOC_EXE}" --ctest-run "${casename}") + # The emitted code defines a TAGS list for every test case that it emits. We use + # these as the LABELS for the test case + unset(labels) + set(labels "${MONGOC_TEST_${casename}_TAGS}") + + # Find what test fixtures the test wants by inspecting labels. Each "uses:" + # label defines the names of the test fixtures that a particular case requires + list_select(labels SELECT "^uses:(.*)$" REPLACE "mongoc/fixtures/\\1" OUT fixtures) + + # For any "lock:..." labels, add a resource lock with the corresponding name + list_select(labels SELECT "^lock:(.*)$" REPLACE "\\1" OUT locks) + + # Tests can set a timeout with a tag: + list_select(labels SELECT "^timeout:(.*)$" REPLACE "\\1" OUT timeout) + if(NOT timeout) + # Default timeout of 10 seconds. If a test takes longer than this, it either + # has a bug or it needs to declare a longer timeout. + set(timeout 10) + endif() + + # Add a label for all test cases generated via this script so that they + # can be (de)selected separately: + list(APPEND labels test-libmongoc-generated) + # Set up the test: + set_tests_properties("${name}" PROPERTIES # test-libmongoc expects to execute in the root of the source directory WORKING_DIRECTORY "${SRC_ROOT}" # If a test emits '@@ctest-skipped@@', this tells us that the test is # skipped. SKIP_REGULAR_EXPRESSION "@@ctest-skipped@@" - # 45 seconds of timeout on each test. - TIMEOUT 45 - FIXTURES_REQUIRED "${all_fixtures}" + # Apply a timeout to each test, either the default or one from test tags + TIMEOUT "${timeout}" + # Common environment variables: ENVIRONMENT "${all_env}" - # Mark all tests generated from the executable, so they can be (de)selected - # for execution separately. - LABELS "test-libmongoc-generated" - ) -endforeach () + # Apply the labels + LABELS "${labels}" + # Fixture requirements: + FIXTURES_REQUIRED "${fixtures}" + # Test may lock resources: + RESOURCE_LOCK "${locks}" + ) +endforeach() diff --git a/build/cmake/MongoC-Warnings.cmake b/build/cmake/MongoC-Warnings.cmake index aad93436e29..f7489137d16 100644 --- a/build/cmake/MongoC-Warnings.cmake +++ b/build/cmake/MongoC-Warnings.cmake @@ -103,4 +103,4 @@ mongoc_add_warning_options ( # Aside: Disable CRT insecurity warnings msvc:/D_CRT_SECURE_NO_WARNINGS - ) +) diff --git a/build/cmake/TestFixtures.cmake b/build/cmake/TestFixtures.cmake index d79d15ae60d..854dfc21c9a 100644 --- a/build/cmake/TestFixtures.cmake +++ b/build/cmake/TestFixtures.cmake @@ -47,3 +47,11 @@ mongo_define_subprocess_fixture( "${_MONGOC_BUILD_SCRIPT_DIR}/bottle.py" fake_kms_provider_server:kms_provider --bind localhost:14987 # Port 14987 chosen arbitrarily ) + +# Run our very simple HTTP server in a fixture process +mongo_define_subprocess_fixture( + mongoc/fixtures/simple-http-server-18000 + SPAWN_WAIT 1 + COMMAND + $ -u "${mongo-c-driver_SOURCE_DIR}/.evergreen/scripts/simple_http_server.py" + ) diff --git a/src/common/src/mlib/config.h b/src/common/src/mlib/config.h index 0cd2292d17a..a95f917efb8 100644 --- a/src/common/src/mlib/config.h +++ b/src/common/src/mlib/config.h @@ -397,4 +397,23 @@ MLIB_IF_GNU_LIKE(mlib_gnu_warning_disable("-Wunused-parameter");) \ MLIB_IF_MSVC(mlib_msvc_warning(disable : 4100);) mlib_static_assert(1, "") +#if mlib_is_clang() +#define mlib_printf_attribute(f, v) __attribute__((format(printf, f, v))) +#elif mlib_is_gcc() +#define mlib_printf_attribute(f, v) __attribute__((format(gnu_printf, f, v))) +#else +#define mlib_printf_attribute(f, v) +#endif + +/** + * @brief Annotate a boolean expression as "likely to be true" to guide the optimizer. + * Use this very sparingly. + */ +#define mlib_likely(...) MLIB_IF_ELSE(mlib_is_gnu_like())(__builtin_expect(!!(__VA_ARGS__), 1))((__VA_ARGS__)) +/** + * @brief Annotate a boolean expression as "likely to be untrue" to guide the optimizer. + * Use this very sparingly. + */ +#define mlib_unlikely(...) MLIB_IF_ELSE(mlib_is_gnu_like())(__builtin_expect(!!(__VA_ARGS__), 0))((__VA_ARGS__)) + #endif // MLIB_CONFIG_H_INCLUDED diff --git a/src/common/src/mlib/str.h b/src/common/src/mlib/str.h index 8f77fffe94f..c3c21a3f5dd 100644 --- a/src/common/src/mlib/str.h +++ b/src/common/src/mlib/str.h @@ -31,8 +31,13 @@ #include #include +#include // va_list #include #include +#include +#include // vsnprintf +#include // malloc/free +#include // memcpy /** * @brief A simple non-owning string-view type. @@ -288,6 +293,24 @@ _mstr_adjust_index(mstr_view s, mlib_upsized_integer pos, bool clamp_to_length) return pos.bits.as_unsigned; } +/** + * @brief Obtain the code unit at the given zero-based index, with negative index wrapping. + * + * This function asserts that the index is in-bounds for the given string. + * + * @param s The string to be inspected. + * @param pos The index to access. Zero is the first code unit, and -1 is the last. + * @return char The code unit at position `pos`. + */ +static inline char +mstr_at(mstr_view s, mlib_upsized_integer pos_) +{ + size_t pos = _mstr_adjust_index(s, pos_, false); + return s.data[pos]; +} + +#define mstr_at(S, Pos) (mstr_at)(mstr_view_from(S), mlib_upsize_integer(Pos)) + /** * @brief Create a new `mstr_view` that views a substring within another string * @@ -441,6 +464,77 @@ mstr_find_first_of(mstr_view hay, mstr_view const needles, mlib_upsized_integer #define _mstr_find_first_of_argc_3(Hay, Needle, Pos) _mstr_find_first_of_argc_4(Hay, Needle, Pos, SIZE_MAX) #define _mstr_find_first_of_argc_4(Hay, Needle, Pos, Len) mstr_find_first_of(Hay, Needle, mlib_upsize_integer(Pos), Len) +/** + * @brief Test whether the given codepoint is a Basic Latin whitespace character + * + * This function does not depend on the locale and has no undefined behavior, unlike functions + * + * @param c The codepoint to be tested + */ +static inline bool +mlib_is_latin_whitespace(int32_t c) +{ + switch (c) { + case 0x09: // horizontal tab + case 0x0a: // line feed + case 0x0d: // carriage return + case 0x20: // space + return true; + + default: + return false; + } +} + +/** + * @brief Trim leading latin (ASCII) whitespace from the given string + * + * @param s The string to be inspected + * @return mstr_view A substring view of `s` that excludes any leading whitespace + */ +static inline mstr_view +mstr_trim_left(mstr_view s) +{ + // Testing arbitrary code units for whitespace is safe as only 1-byte-encoded + // codepoints can land within the Basic Latin range: + while (s.len && mlib_is_latin_whitespace(mstr_at(s, 0))) { + s = mstr_substr(s, 1); + } + return s; +} +#define mstr_trim_left(S) (mstr_trim_left)(mstr_view_from(S)) + +/** + * @brief Trim trailing latin (ASCII) whitespace from the given string + * + * @param s The string to be insepcted + * @return mstr_view A substring view of `s` that excludes any trailing whitespace. + */ +static inline mstr_view +mstr_trim_right(mstr_view s) +{ + while (s.len && mlib_is_latin_whitespace(mstr_at(s, -1))) { + s = mstr_slice(s, 0, -1); + } + return s; +} +#define mstr_trim_right(S) (mstr_trim_right)(mstr_view_from(S)) + +/** + * @brief Trim leading and trailing latin (ASCII) whitespace from the string + * + * @param s The string to be inspected + * @return mstr_view A substring of `s` that excludes leading and trailing whitespace. + */ +static inline mstr_view +mstr_trim(mstr_view s) +{ + s = mstr_trim_left(s); + s = mstr_trim_right(s); + return s; +} +#define mstr_trim(S) (mstr_trim)(mstr_view_from(S)) + /** * @brief Split a single string view into two strings at the given position * @@ -565,4 +659,568 @@ mstr_contains_any_of(mstr_view str, mstr_view needle) } #define mstr_contains_any_of(Str, Needle) mstr_contains_any_of(mstr_view_from(Str), mstr_view_from(Needle)) + +/** + * @brief A simple mutable string type, with a guaranteed null terminator. + * + * This type is a trivially relocatable aggregate type that contains a pointer `data` + * and a size `len`. If not null, the pointer `data` points to an array of mutable + * `char` of length `len + 1`, where the character at `data[len]` is always zero, + * and must not be modified. + * + * @note The string MAY contain nul (zero-value) characters, so using them with + * C string APIs could truncate unexpectedly. + * @note The string itself may be "null" if the `data` member of the string is + * a null pointer. A zero-initialized `mstr` is null. The null string is distinct + * from the empty string, which has a non-null `.data` that points to an empty + * C string. + */ +typedef struct mstr { + /** + * @brief Pointer to the first char in the string, or NULL if + * the string is null. + * + * The pointed-to character array has a length of `len + 1`, where + * the character at `data[len]` is always null. + * + * @warning Attempting to overwrite the null character at `data[len]` + * will result in undefined behavior! + * + * @note An empty string is not equivalent to a null string! An empty string + * will still point to an array of length 1, where the only char is the null + * terminator. + */ + char *data; + /** + * @brief The number of characters in the array pointed-to by `data` + * that precede the null terminator. + */ + size_t len; +} mstr; + + +/** + * @brief Resize an existing or null `mstr`, without initializing any of the + * added content other than the null terminator. This operation is potentially + * UNSAFE, because it gives uninitialized memory to the caller. + * + * @param str Pointer to a valid `mstr`, or a null `mstr`. + * @param new_len The new length of the string. + * @return true If the operation succeeds + * @return false Otherwise + * + * If `str` is a null string, this function will initialize a new `mstr` object + * on-the-fly. + * + * If the operation increases the length of the string (or initializes a new string), + * then the new `char` in `str.data[str.len : new_len] will contain uninitialized + * values. The char at `str.data[new_len]` WILL be set to zero, to ensure there + * is a null terminator. The caller should always initialize the new string + * content to ensure that the string has a specified value. + */ +static inline bool +mstr_resize_for_overwrite(mstr *const str, const size_t new_len) +{ + // We need to allocate one additional char to hold the null terminator + size_t alloc_size = new_len; + if (mlib_unlikely(mlib_add(&alloc_size, 1) || alloc_size > PTRDIFF_MAX)) { + // Allocation size is too large + return false; + } + // Try to (re)allocate the region + char *data = (char *)realloc(str->data, alloc_size); + if (!data) { + // Failed to (re)allocate + return false; + } + // Note: We do not initialize any of the data in the newly allocated region. + // We only set the null terminator. It is up to the caller to do the rest of + // the init. + data[new_len] = '\0'; + // Update the final object + str->data = data; + str->len = new_len; + // Success + return true; +} + +/** + * @brief Given an existing `mstr`, resize it to hold `new_len` chars + * + * @param str Pointer to a string object to update, or a null `mstr` + * @param new_len The new length of the string, not including the implicit null terminator + * @return true If the operation succeeds + * @return false Otherwise + * + * @note If the operation fails, then `*str` is not modified. + */ +static inline bool +mstr_resize(mstr *str, size_t new_len) +{ + const size_t old_len = str->len; + if (!mstr_resize_for_overwrite(str, new_len)) { + // Failed to allocate new storage for the string + return false; + } + // Check how many chars we added/removed + const ptrdiff_t len_diff = mlib_assert_sub(ptrdiff_t, new_len, str->len); + if (len_diff > 0) { + // We added new chars. Zero-init all the new chars + memset(str->data + old_len, 0, (size_t)len_diff); + } + // Success + return true; +} + +/** + * @brief Create a new `mstr` of the given length + * + * @param new_len The length of the new string, in characters, not including the null terminator + * @return mstr A new string. The string's `data` member is NULL in case of failure + * + * The character array allocated for the string will always be `new_len + 1` `char` in length, + * where the char at the index `new_len` is a null terminator. This means that a string of + * length zero will allocate a single character to store the null terminator. + * + * All characters in the new string are initialize to zero. If you want uninitialized + * string content, use `mstr_resize_for_overwrite`. + */ +static inline mstr +mstr_new(size_t new_len) +{ + mstr ret = {NULL, 0}; + // We can rely on `resize` to handle the null state properly. + mstr_resize(&ret, new_len); + return ret; +} + +/** + * @brief Free the resources associated with an mstr object. + * + * @param s Pointer to an `mstr` object. If pointer or the pointed-to-object is null, + * this function is a no-op. + * + * After this call, the pointed-to `s` will be a null `mstr` + */ +static inline void +mstr_destroy(mstr *s) +{ + if (s) { + free(s->data); + s->len = 0; + s->data = NULL; + } +} + +/** + * @brief Obtain a null mstr string object. + * + * @return mstr A null string, with a null data pointer and zero size + */ +static inline mstr +mstr_null(void) +{ + return mlib_init(mstr){0}; +} + +/** + * @internal + * @brief Test whether the given string-view is a view within the given owning string + */ +static inline bool +_mstr_overlaps(mstr const *str, mstr_view sv) +{ + // Note: Pointer-comparison between objects is unspecified, but is guaranteed + // to returns `true` if there is overlap. We're okay with false-positive overlaps. + // Additionally, POSIX and Win32 both offer stronger guarantees about pointer + // comparison, which we can rely on here. + return str->data // + && str->data <= sv.data // + && sv.data <= str->data + str->len; +} + +/** + * @brief Replace the content of the given string, attempting to reuse the buffer + * + * @param inout Pointer to a valid or null `mstr` to be replaced + * @param s The new string contents + * @return true If the operation succeeded + * @return false Otherwise + * + * If the operation fails, `*inout` is not modified + */ +static inline bool +mstr_assign(mstr *inout, mstr_view s) +{ + // Check for self-assignment + if (_mstr_overlaps(inout, s)) { + // We are overwriting a string with a (sub)string of its own content. + // Move the substring to the front of the string (may be a no-op if `s` + // points to the beginning of the string) + memmove(inout->data, s.data, s.len); + // Resize to truncate. This will always shrink the string, because a valid + // string-view into `inout` cannot be longer than `inout` itself. Thus, it + // also cannot fail. + mstr_resize_for_overwrite(inout, s.len); + return true; + } + if (!mstr_resize_for_overwrite(inout, s.len)) { + return false; + } + memcpy(inout->data, s.data, s.len); + return true; +} + +#define mstr_assign(InOut, S) mstr_assign((InOut), mstr_view_from((S))) + +/** + * @brief Create a mutable copy of the given string. + * + * @param sv The string to be copied + * @return mstr A new valid string, or a null string in case of allocation failure. + */ +static inline mstr +mstr_copy(mstr_view sv) +{ + mstr ret = {NULL, 0}; + mstr_assign(&ret, sv); + return ret; +} + +#define mstr_copy(S) mstr_copy(mstr_view_from((S))) +#define mstr_copy_cstring(S) mstr_copy(mstr_cstring((S))) + +/** + * @brief Concatenate two strings into a new mutable string + * + * @param a The left-hand string to be concatenated + * @param b The right-hand string to be concatenated + * @return mstr A new valid string composed by concatenating `a` with `b`, or + * a null string in case of allocation failure. + */ +static inline mstr +mstr_concat(mstr_view a, mstr_view b) +{ + mstr ret = {NULL, 0}; + size_t cat_len = 0; + if (mlib_unlikely(mlib_add(&cat_len, a.len, b.len))) { + // Size would overflow. No go. + return ret; + } + // Prepare the new string + if (!mstr_resize_for_overwrite(&ret, cat_len)) { + // Failed to allocate. The ret string is still null, and we can just return it + return ret; + } + // Copy in the characters from `a` + char *out = ret.data; + memcpy(out, a.data, a.len); + // Copy in the characters from `b` + out += a.len; + memcpy(out, b.data, b.len); + // Success + return ret; +} + +#define mstr_concat(A, B) mstr_concat(mstr_view_from((A)), mstr_view_from((B))) + +/** + * @brief Delete and/or insert characters into a string + * + * @param str The string object to be updated + * @param splice_pos The position at which to do the splice + * @param n_delete The number of characters to delete at `splice_pos` + * @param insert A string to be inserted at `split_pos` after chars are deleted + * @return true If the operation succeeds + * @return false Otherwise + * + * If `n_delete` is zero, then no characters are deleted. If `insert` is empty + * or null, then no characters are inserted. + */ +static inline bool +mstr_splice(mstr *str, size_t splice_pos, size_t n_delete, mstr_view insert) +{ + // Guard against self-insertion: + if (insert.data && _mstr_overlaps(str, insert)) { + // The insertion string exists within the current string. We cannot modify it in-place. + // Duplicate the insertion string to remain pristine while we splice: + mstr insert_dup = mstr_copy(insert); + if (!insert_dup.data) { + // Failed to dup the insert string. Failure to splice + return false; + } + // Do the splice, now using the copy of the insertion string + const bool ok = mstr_splice(str, splice_pos, n_delete, mstr_view_from(insert_dup)); + // We're done with the dup + mstr_destroy(&insert_dup); + // Return the sub-result + return ok; + } + mlib_check(splice_pos <= str->len); + // How many chars is it possible to delete from `splice_pos`? + size_t n_chars_avail_to_delete = str->len - splice_pos; + // Clamp to the number of chars available for deletion: + if (n_delete > n_chars_avail_to_delete) { + n_delete = n_chars_avail_to_delete; + } + // Compute the new string length + size_t new_len = str->len; + // This should never fail, because we should never try to delete more chars than we have + mlib_check(!mlib_sub(&new_len, n_delete)); + // Check if appending would make too big of a string + if (mlib_unlikely(mlib_add(&new_len, insert.len))) { + // New string will be too long + return false; + } + char *mut = str->data; + // We either resize first or resize last, depending on where we are shifting chars + if (new_len > str->len) { + // Do the resize first + if (!mstr_resize_for_overwrite(str, new_len)) { + // Failed to allocate + return false; + } + mut = str->data; + } + // Move to the splice position + mut += splice_pos; + // Shift the existing string parts around for the deletion operation + const size_t tail_len = n_chars_avail_to_delete - n_delete; + // Adjust to the begining of the string part that we want to keep + char *copy_from = mut + n_delete; + char *copy_to = mut + insert.len; + memmove(copy_to, copy_from, tail_len); + if (new_len < str->len) { + // We didn't resize first, so resize now. We are shrinking the string, so this + // will never fail, and does not create any uninitialized memory: + mlib_check(mstr_resize_for_overwrite(str, new_len)); + mut = str->data + splice_pos; + } + // Insert the new data if the insertion string is non-null + if (insert.data) { + memcpy(mut, insert.data, insert.len); + } + return true; +} + +/** + * @brief Append a string to the end of some other string. + * + * @param str The string to be modified + * @param suffix The suffix string to be appended onto `*str` + * @return true If the operation was successful + * @return false Otherwise + * + * If case of failure, `*str` is not modified. + */ +static inline bool +mstr_append(mstr *str, mstr_view suffix) +{ + return mstr_splice(str, str->len, 0, suffix); +} + +#define mstr_append(Into, Suffix) mstr_append((Into), mstr_view_from((Suffix))) + +/** + * @brief Append a single character to the given string object + * + * @param str The string object to be updated + * @param c The single character that will be inserted at the end + * @return true If the operation succeeded + * @return false Otherwise + * + * In case of failure, the string is not modified. + */ +static inline bool +mstr_append_char(mstr *str, char c) +{ + mstr_view one = mstr_view_data(&c, 1); + return mstr_append(str, one); +} + +/** + * @brief Replace every occurrence of `needle` in `str` with `sub` + * + * @param str The string object to be updated + * @param needle The non-empty needle string to be searched for.s + * @param sub The string to be inserted in place of each `needle` + * @return true If the operation succeeds + * @return false Otherwise + * + * @note If the `needle` string is empty, then the substitution string will + * be inserted around and between every byte in the string: + * + * replace("foo", "", "|") -> "|f|o|o|" + * + * @note The operation is guaranteed to never fail if the `sub` string is not + * longer than the `needle` string AND the needle and sub strings do not overlap + * + * @note If the operation fails, the content of `str` is an unspecified but valid + * string. + */ +static inline bool +mstr_replace(mstr *str, mstr_view needle, mstr_view sub) +{ + bool okay = true; + // We may dup the needle/sub if they overlap the output string + mstr needle_dup = mstr_null(); + mstr sub_dup = mstr_null(); + // Check if the needle is a substring of the target: + if (_mstr_overlaps(str, needle)) { + // Copy the needle string + needle_dup = mstr_copy(needle); + // Detect allocation failure: + okay = !!needle_dup.data; + // Update the needle to point to the duplicate: + needle = mstr_view_from(needle_dup); + } + // Do the same with the sub string: + if (okay && _mstr_overlaps(str, sub)) { + sub_dup = mstr_copy(sub); + okay = !!needle_dup.data; + sub = mstr_view_from(sub_dup); + } + // Scan forward, starting from the first position: + size_t off = 0; + while (okay && off <= str->len) { + // Find the next occurrence, starting from the scan offset + off = mstr_find(*str, needle, off); + if (off == SIZE_MAX) { + // No more occurrences. + break; + } + // Replace the needle string with the new value + if (!mstr_splice(str, off, needle.len, sub)) { + okay = false; + } + // Advance over the length of the replacement string, so we don't try to + // infinitely replace content if the replacement itself contains the needle + // string + if (mlib_unlikely(mlib_add(&off, sub.len))) { + // Integer overflow while advancing the offset. No good. + okay = false; + } + // Note: To support empty needles, advance one more space to avoid infinite + // repititions in-place. + // TODO: To do this "properly", this should instead advance over a full UTF-8-encoded + // codepoint. For now, just do a single byte. + if (!needle.len && mlib_unlikely(mlib_add(&off, 1))) { + // Advancing the extra distance failed + okay = false; + } + } + // Destroy the needle/sub strings, which we may have duplicated if they overlapped + // the target. If not, then these are a no-op. + mstr_destroy(&needle_dup); + mstr_destroy(&sub_dup); + return okay; +} + +/** + * @brief Like `mstr_sprintf`, but accepts a `va_list` directly. + */ +mlib_printf_attribute(1, 0) static inline mstr mstr_vsprintf(const char *format, va_list args) +{ + size_t format_strlen = strlen(format); + size_t sz = format_strlen; + if (mlib_unlikely(mlib_mul(&sz, 2))) { + // Overflow on multiply. Oof + sz = format_strlen; + } + + mstr ret = mstr_null(); + while (1) { + // Resize to make room for the formatted text + if (!mstr_resize(&ret, sz)) { + // Allocation failure + break; + } + + // Calc the size with the null terminator + size_t len_with_null = ret.len; + if (mlib_unlikely(mlib_add(&len_with_null, 1))) { + // Unlikely: Overflow + break; + } + + // Do the formatting + va_list dup_args; + va_copy(dup_args, args); + int n_chars = vsnprintf(ret.data, len_with_null, format, dup_args); + va_end(dup_args); + + // On error, returns a negative value + if (n_chars < 0) { + break; + } + + if ((size_t)n_chars <= ret.len) { + // Success. Truncate to the number of chars actually written: + mstr_resize(&ret, (size_t)n_chars); + // Return the successfully formatted string: + return ret; + } + + // Need more room. Resize and try again: + sz = (size_t)n_chars; + continue; + } + + // Only reached if the operation failed + mstr_destroy(&ret); + return ret; +} + +/** + * @brief Format a string according to `printf` rules + * + * @param f The format string to be used. + * @param ... The formatting arguments to interpolate into the string + * @return mstr A new mstr upon success, or a null mstr upon failure. + */ +mlib_printf_attribute(1, 2) static inline mstr mstr_sprintf(const char *f, ...) +{ + va_list args; + va_start(args, f); + mstr ret = mstr_vsprintf(f, args); + va_end(args); + return ret; +} + +/** + * @brief Like `mstr_sprintf_append`, but accepts the va_list directly. + */ +mlib_printf_attribute(2, 0) static inline bool mstr_vsprintf_append(mstr *string, const char *format, va_list args) +{ + mlib_check(string != NULL, because, "Output string parameter is required"); + mstr suffix = mstr_vsprintf(format, args); + bool ok = mstr_append(string, suffix); + mstr_destroy(&suffix); + return ok; +} + +/** + * @brief Append content to a string using `printf()` style formatting. + * + * @param string Pointer to a valid or null string object which will be modified + * @param format A printf-style format string to append onto `string` + * @param ... The interpolation arguments for `format` + * + * @retval true If-and-only-if the string is successfully modified + * @retval false If there was an error during formatting. The content of `string` + * is unspecified. + * + * This function maintains the existing content of `string` and only inserts + * additional characters at the end of the string. + */ +mlib_printf_attribute(2, 3) static inline bool mstr_sprintf_append(mstr *string, const char *format, ...) +{ + va_list args; + va_start(args, format); + const bool okay = mstr_vsprintf_append(string, format, args); + va_end(args); + return okay; +} + + #endif // MLIB_STR_H_INCLUDED diff --git a/src/common/src/mlib/str_vec.h b/src/common/src/mlib/str_vec.h new file mode 100644 index 00000000000..8a69e6383e9 --- /dev/null +++ b/src/common/src/mlib/str_vec.h @@ -0,0 +1,31 @@ +/** + * @file str_vec.h + * @brief This file defines mstr_vec, a common "array of strings" type + * @date 2025-09-30 + * + * @copyright Copyright 2009-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef MLIB_STR_VEC_H_INCLUDED +#define MLIB_STR_VEC_H_INCLUDED + +#include +#include + +#define T mstr +#define VecDestroyElement(Ptr) (mstr_destroy(Ptr)) +#define VecCopyElement(Dst, Src) (*Dst = mstr_copy(*Src), Dst->data != NULL) +#include + +#endif // MLIB_STR_VEC_H_INCLUDED diff --git a/src/common/src/mlib/test.h b/src/common/src/mlib/test.h index 4527b2f3e91..c0f937fade9 100644 --- a/src/common/src/mlib/test.h +++ b/src/common/src/mlib/test.h @@ -129,56 +129,98 @@ typedef struct mlib_source_location { #define mlib_check(...) MLIB_ARGC_PICK(_mlib_check, #__VA_ARGS__, __VA_ARGS__) // One arg: #define _mlib_check_argc_2(ArgString, Condition) \ - _mlibCheckConditionSimple(Condition, ArgString, mlib_this_source_location()) + _mlibCheckConditionSimple(Condition, ArgString, NULL, mlib_this_source_location()) // Three args: #define _mlib_check_argc_4(ArgString, A, Operator, B) \ - MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B) + MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B, NULL) +// Five args: +#define _mlib_check_argc_6(ArgString, A, Operator, B, Infix, Reason) \ + MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlib_check_with_suffix_, Infix)(A, Operator, B, Reason) +#define _mlib_check_with_suffix_because(A, Operator, B, Reason) \ + MLIB_NOTHING(#A, #B) MLIB_PASTE(_mlibCheckCondition_, Operator)(A, B, Reason) // String-compare: -#define _mlibCheckCondition_str_eq(A, B) _mlibCheckStrEq(A, B, #A, #B, mlib_this_source_location()) +#define _mlibCheckCondition_str_eq(A, B, Reason) _mlibCheckStrEq(A, B, #A, #B, Reason, mlib_this_source_location()) // Pointer-compare: -#define _mlibCheckCondition_ptr_eq(A, B) _mlibCheckPtrEq(A, B, #A, #B, mlib_this_source_location()) +#define _mlibCheckCondition_ptr_eq(A, B, Reason) _mlibCheckPtrEq(A, B, #A, #B, Reason, mlib_this_source_location()) // Integer-equal: -#define _mlibCheckCondition_eq(A, B) \ - _mlibCheckIntCmp( \ - mlib_equal, true, "==", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) +#define _mlibCheckCondition_eq(A, B, Reason) \ + _mlibCheckIntCmp(mlib_equal, \ + true, \ + "==", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) // Integer not-equal: -#define _mlibCheckCondition_neq(A, B) \ - _mlibCheckIntCmp( \ - mlib_equal, false, "≠", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) -// Simple assertion with an explanatory string -#define _mlibCheckCondition_because(Cond, Msg) _mlibCheckConditionBecause(Cond, #Cond, Msg, mlib_this_source_location()) +#define _mlibCheckCondition_neq(A, B, Reason) \ + _mlibCheckIntCmp(mlib_equal, \ + false, \ + "!=", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) // Integer comparisons: -#define _mlibCheckCondition_lt(A, B) \ - _mlibCheckIntCmp( \ - mlib_less, true, "<", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) -#define _mlibCheckCondition_lte(A, B) \ - _mlibCheckIntCmp( \ - mlib_greater, false, "≤", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) -#define _mlibCheckCondition_gt(A, B) \ - _mlibCheckIntCmp( \ - mlib_greater, true, ">", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) -#define _mlibCheckCondition_gte(A, B) \ - _mlibCheckIntCmp( \ - mlib_less, false, "≥", mlib_upsize_integer(A), mlib_upsize_integer(B), #A, #B, mlib_this_source_location()) +#define _mlibCheckCondition_lt(A, B, Reason) \ + _mlibCheckIntCmp(mlib_less, \ + true, \ + "<", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) +#define _mlibCheckCondition_lte(A, B, Reason) \ + _mlibCheckIntCmp(mlib_greater, \ + false, \ + "≤", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) +#define _mlibCheckCondition_gt(A, B, Reason) \ + _mlibCheckIntCmp(mlib_greater, \ + true, \ + ">", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) +#define _mlibCheckCondition_gte(A, B, Reason) \ + _mlibCheckIntCmp(mlib_less, \ + false, \ + "≥", \ + mlib_upsize_integer(A), \ + mlib_upsize_integer(B), \ + #A, \ + #B, \ + Reason, \ + mlib_this_source_location()) + +// Simple assertion with an explanatory string +#define _mlibCheckCondition_because(Cond, Reason, _null) \ + _mlibCheckConditionSimple(Cond, #Cond, Reason, mlib_this_source_location()) /// Check evaluator when given a single boolean static inline void -_mlibCheckConditionSimple(bool c, const char *expr, struct mlib_source_location here) +_mlibCheckConditionSimple(bool c, const char *expr, const char *reason, struct mlib_source_location here) { if (!c) { - fprintf(stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed\n", here.file, here.lineno, here.func, expr); - fflush(stderr); - abort(); - } -} - -static inline void -_mlibCheckConditionBecause(bool cond, const char *expr, const char *reason, mlib_source_location here) -{ - if (!cond) { - fprintf( - stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed (%s)\n", here.file, here.lineno, here.func, expr, reason); + fprintf(stderr, "%s:%d: in [%s]: Check condition ⟨%s⟩ failed", here.file, here.lineno, here.func, expr); + if (reason) { + fprintf(stderr, " (%s)", reason); + } + fprintf(stderr, "\n"); fflush(stderr); abort(); } @@ -193,6 +235,7 @@ _mlibCheckIntCmp(enum mlib_cmp_result cres, // The cmp result to check struct mlib_upsized_integer right, const char *left_expr, const char *right_expr, + const char *reason, struct mlib_source_location here) { if (((mlib_cmp)(left, right, 0) == cres) != cond) { @@ -218,6 +261,9 @@ _mlibCheckIntCmp(enum mlib_cmp_result cres, // The cmp result to check fprintf(stderr, "%llu", (unsigned long long)right.bits.as_unsigned); } fprintf(stderr, " ⟨%s⟩\n", right_expr); + if (reason) { + fprintf(stderr, "Because: %s\n", reason); + } fflush(stderr); abort(); } @@ -225,8 +271,12 @@ _mlibCheckIntCmp(enum mlib_cmp_result cres, // The cmp result to check // Pointer-comparison static inline void -_mlibCheckPtrEq( - const void *left, const void *right, const char *left_expr, const char *right_expr, struct mlib_source_location here) +_mlibCheckPtrEq(const void *left, + const void *right, + const char *left_expr, + const char *right_expr, + const char *reason, + struct mlib_source_location here) { if (left != right) { fprintf(stderr, @@ -243,6 +293,9 @@ _mlibCheckPtrEq( left_expr, right, right_expr); + if (reason) { + fprintf(stderr, "Because: %s\n", reason); + } fflush(stderr); abort(); } @@ -250,8 +303,12 @@ _mlibCheckPtrEq( // String-comparison static inline void -_mlibCheckStrEq( - const char *left, const char *right, const char *left_expr, const char *right_expr, struct mlib_source_location here) +_mlibCheckStrEq(const char *left, + const char *right, + const char *left_expr, + const char *right_expr, + const char *reason, + struct mlib_source_location here) { if (strcmp(left, right)) { fprintf(stderr, @@ -268,6 +325,9 @@ _mlibCheckStrEq( left_expr, right, right_expr); + if (reason) { + fprintf(stderr, "Because: %s\n", reason); + } fflush(stderr); abort(); } diff --git a/src/common/src/mlib/vec.th b/src/common/src/mlib/vec.th new file mode 100644 index 00000000000..453b80c9fbe --- /dev/null +++ b/src/common/src/mlib/vec.th @@ -0,0 +1,466 @@ +/** + * @file vec.th + * @brief Declare a new vector container data type + * @date 2024-10-02 + * + * To use this file: + * + * - #define a type `T` immediately before including this file. + * - Optional: Define an identifier `VecName` to the name of the vector. If unset, declares `_vec` + * - Optional: Define a `VecDestroyElement(Ptr)` macro to specify how the vector + * should destroy the element at `*Ptr`. If unset, destroying is a no-op. + * - Optional: Define `VecInitElement(Ptr, ...)` which initializes a new element. + * The first macro argument is a pointer to the element and subsequent arguments + * are unspecified and reserved for future use. Elements are zero-initialized + * before being passed to this macro. + * - Optional: Define `VecCopyElement(DstPtr, SrcPtr)` to copy data from `*SrcPtr` + * to `*DstPtr`. The vector's copying function is only defined if this macro + * is defined. This macro MUST evaluate to a boolean to indicate if the copy + * operation succeeded. If a copy fails, then the partially copied elements + * will be destroyed and the overall copy will fail. + * + * To add a trival copying function, define `VecCopyElement` to + * `VecTrivialCopyElement`. + * + * - NOTE: All of the above macros will be automatically undef'd after this file + * is included. + * + * Types stored in the vector must be trivially relocatable. + * + * @copyright Copyright 2009-present MongoDB, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include + +#include // assert +#include // bool +#include // size_t +#include // calloc, realloc, free +#include // memcpy, memset + +// Check that the caller provided a `T` macro to be the element type +#ifndef T +#if defined(__clangd__) || defined(__INTELLISENSE__) +#define T int // Define a type for IDE diagnostics +#define VecCopyElement VecTrivialCopyElement // For IDE highlighting +#else +#error A type `T` should be defined before including this file +#endif +#endif + +#ifndef VecName +#define VecName MLIB_PASTE(T, _vec) +#endif + +#ifndef VecDestroyElement +#define VecDestroyElement(Ptr) ((void)(Ptr)) +#endif + +#ifndef VecInitElement +#define VecInitElement(Ptr) ((void)(Ptr)) +#endif + +#ifndef VecTrivialCopyElement +#define VecTrivialCopyElement(DstPtr, SrcPtr) ((*(DstPtr) = *(SrcPtr)), true) +#endif + +#pragma push_macro("vec_inline_spec") +#if !defined(vec_inline_spec) +#define vec_inline_spec static inline +#endif + +// The "fn" macro just adds a qualified name to the front of a function identifier +#pragma push_macro("fn") +#undef fn +#define fn(M) MLIB_PASTE_3(VecName, _, M) + +typedef struct VecName { + /** + * @private + * @brief Pointer to the first vector element, or NULL if the vector is + * empty. + * + * @note DO NOT DIRECTLY MODIFY THIS VALUE + */ + T *data; + /** + * @brief The number of elements in the vector. + * + * @note DO NOT DIRECTLY MODIFY THIS VALUE + */ + size_t size; + /** + * @brief The number of allocated storage elements. + * + * @note DO NOT DIRECTLY MODIFY THIS VALUE + */ + size_t capacity; + +#if mlib_is_cxx() + T * + begin() noexcept + { + return data; + } + T * + end() noexcept + { + return data ? data + size : data; + } +#endif +} VecName; + +mlib_extern_c_begin(); + +/** + * @brief Obtain a pointer-to-mutable to the first element in the given vector + */ +vec_inline_spec T * +fn(begin(VecName *v)) mlib_noexcept +{ + return v->data; +} + +/** + * @brief Obtain a pointer-to-mutable past the last element in the given vector + */ +vec_inline_spec T * +fn(end(VecName *v)) mlib_noexcept +{ + return v->data ? v->data + v->size : v->data; +} + +/** + * @brief Obtain a pointer-to-const to the first element in the given vector + */ +vec_inline_spec T const * +fn(cbegin(VecName const *v)) mlib_noexcept +{ + return v->data; +} + +/** + * @brief Obtain a pointer-to-const past the last element in the given vector + */ +vec_inline_spec T const * +fn(cend(VecName const *v)) mlib_noexcept +{ + return v->data ? v->data + v->size : v->data; +} + +/** + * @brief Get the maximum number of elements that can be held in the vector of + * a certain type. + */ +vec_inline_spec size_t +fn(max_size(void)) mlib_noexcept +{ + // We compare against (signed) PTRDIFF_MAX because want to support the difference + // between two pointers. If we use the unsigned size, then we could have vectors + // with size that is too large to represent the difference between two sizes. + return PTRDIFF_MAX / sizeof(T); +} + +/** + * @brief Set the capacity of the given vector. + * + * @param self The vector object to be modified + * @param count The new capacity. If this is less than the current size, then + * the capacity will be capped at the size instead + * + * @retval true If-and-only-if the reallocation was successful + * @retval false If there was an error in allocating the buffer + */ +vec_inline_spec bool +fn(reserve(VecName *const self, size_t count)) mlib_noexcept +{ + // Check if this value is beyond the possible capacity of the vector + if (count > fn(max_size())) { + // Too many elements. We cannot allocate a region this large. + return false; + } + // Check if we are already at the requested capacity. + if (count == self->capacity) { + // No reallocation needed. + return true; + } + // Check if the caller is requesting a lower capacity than our current size + if (count < self->size) { + // We cannot shrink the capacity below the current size, so just shrink-to-fit + count = self->size; + } + // Impossible: We will never shrink below `self.size`, and if + // `self.size == 0` and `count == 0`, then we early-return'd above. + assert(count != 0); + // The number of bytes we need to allocate. Note that this cannot overflow + // because we guard against it by checking against `max_size()` + const size_t new_buffer_size = count * sizeof(T); + // Attempt to reallocate the region + T *const new_buffer = (T *)realloc(self->data, new_buffer_size); + if (!new_buffer) { + // Failed to reallocate a new storage region + return false; + } + // Successfully reallocated the buffer. Update our storage pointer. + self->data = new_buffer; + // Note the new capacity. + self->capacity = count; + return true; +} + +/** + * @brief Destroy elements in the vector at the specified range positions + * + * @param self The vector to be updated + * @param first Pointer to the first element to be destroyed + * @param last Pointer to the first element to NOT be destroyed + * + * Elements are destroyed and removed starting at the end. If `first == last`, + * this is a no-op. The given pointers must refer to vector elements, and `last` + * must be reachable by advancing `first` zero or more times. + */ +vec_inline_spec void +fn(erase(VecName *const self, T *const first, T *const last)) +{ + // Number of elements following the removed region + const size_t n_tail_elements = (size_t)(fn(end(self)) - last); + // Destroy elements in reverse order: + for (T *r_iter = last; r_iter != first; --r_iter) { + VecDestroyElement((r_iter - 1)); + --self->size; + } + // This mult cannot overflow because we can never contain enough elements to overflow PTRDIFF_MAX + const size_t n_bytes_to_shift = n_tail_elements * sizeof(T); + // If there are any elements to be shifted, shift them down over the removed region + if (n_bytes_to_shift) { + // Shift all tail elements down into their new position + memmove(first, last, n_bytes_to_shift); + } +} + +/** + * @brief Destroy a single element at the given zero-based index position + */ +vec_inline_spec void +fn(erase_at(VecName *const self, size_t pos)) +{ + fn(erase(self, fn(begin(self)) + pos, fn(end(self)))); +} + +/** + * @brief Resize the vector to hold the given number of elements + * + * Newly added elements are zero-initialized, or initailized using VecInitElement + * + * @retval true If-and-only-if the resize was successful + * @retval false If the function failed to allocate the new storage region + * + * @note Don't forget to check the return value for success! + */ +// mlib_nodiscard ("Check the returned bool to detect allocation failure") +vec_inline_spec bool +fn(resize(VecName *const self, size_t const count)) mlib_noexcept +{ + // Check if we aren't actually growing the vector. + if (count <= self->size) { + // We need to destroy elements at the tail. If `count == size`, this is a no-op. + if (self->data) { + fn(erase(self, fn(begin(self)) + count, fn(end(self)))); + } + return true; + } + + // We need to increase the capacity of the vector to hold the new elements + // Try to auto-grow capacity. Increase capacity by ×1.5 + const size_t half_current_capacity = self->capacity / 2; + size_t new_capacity = 0; + if (mlib_unlikely(mlib_add(&new_capacity, self->size, half_current_capacity))) { + // The auto growth amount would overflow, so just cap to the max size. + new_capacity = fn(max_size()); + } + // Check if our automatic growth is big enough to hold the requested number of elements + if (new_capacity < count) { + // The automatic growth factor is actually smaller than the number of new elements + // the caller wants, so we need to increase capacity to that level instead. + new_capacity = count; + } + // Try to reserve more storage + if (!fn(reserve(self, new_capacity))) { + // We failed to reserve the new storage region. The requested capacity may be too large, + // or we may have just run out of memory. + return false; + } + + // Pointer to where the new end will be + T *const new_end = fn(begin(self)) + count; + // Create a zero-initialized object to copy over the top of each new element. + T zero; + memset(&zero, 0, sizeof zero); + // Call init() on ever new element up until the new size + for (T *iter = fn(end(self)); iter != new_end; ++iter) { + *iter = zero; + (void)(VecInitElement((iter))); + } + + // Update the stored size + self->size = count; + return true; +} + +/** + * @brief Append another element, returning a pointer to that element. + * + * @return T* A pointer to the newly added element, or NULL in case of allocation failure. + */ +// mlib_nodiscard ("Check the returned pointer for failure") +vec_inline_spec T * +fn(push(VecName *self)) mlib_noexcept +{ + size_t count = self->size; + if (mlib_unlikely(mlib_add(&count, 1))) { + // Adding another element would overflow size_t. This is extremely unlikely, + // but precautionary. + return NULL; + } + if (!fn(resize(self, count))) { + // Failed to push another item + return NULL; + } + return fn(begin(self)) + count - 1; +} + +/** + * @brief Create a new empty vector + */ +vec_inline_spec VecName fn(new(void)) mlib_noexcept +{ + VecName ret = {NULL, 0, 0}; + return ret; +} + +/** + * @brief Destroy the pointed-to vector, freeing the associated data buffer. + * + * The pointed-to vector becomes valid storage for a new vector object. + */ +vec_inline_spec void +fn(destroy(VecName *self)) mlib_noexcept +{ + // Resizing to zero will destroy all elements + (void)fn(resize(self, 0)); + // Resizing won't necessarily free the data buffer. Do that now. + free(self->data); + self->capacity = 0; + self->data = NULL; +} + +/** + * @brief Create a new vector with `n` initialized elements + */ +vec_inline_spec VecName +fn(new_n(size_t n, bool *okay)) mlib_noexcept +{ + VecName ret = fn(new()); + *okay = fn(resize)(&ret, n); + return ret; +} + +#ifdef VecCopyElement +/** + * @brief Copy the data from the vector `src` into storage for a new vector `dst` + * + * @param dst_vec Pointer-to-storage for a new vector object to be initialized. + * @param src_vec Pointer to a vector whose elements will be copied into a new vector + * @retval true If-and-only-if the copy was successful. + * @retval false Otherwise + */ +vec_inline_spec bool +fn(init_copy(VecName *dst_vec, VecName const *src_vec)) mlib_noexcept +{ + VecName tmp = fn(new()); + // Try to reseve capacity for all new elements. Don't resize(), because we want + // uninitialized storage for the new data. + if (!fn(reserve(&tmp, src_vec->size))) { + // We failed to reserve capacity in the new vector + fn(destroy(&tmp)); + return false; + } + // Copy everything into the destination element-by-element + { + // Input iterator + T const *in_iter = fn(cbegin(src_vec)); + // Input stop position + T const *const in_stop = fn(cend(src_vec)); + // Output iterator + T *out_iter = tmp.data; + // Copy from the first to the last + for (; in_iter != in_stop; ++in_iter, ++out_iter) { + // Try to copy into the new element + if (!VecCopyElement((out_iter), (in_iter))) { + // Failed copying here. Undo everything by destroying the temporary + fn(destroy(&tmp)); + return false; + } + // Update the size of the temporary vec to record that it is holding the new + // element. This allows us to call `destroy()` to undo our work. + tmp.size++; + } + } + // Everything went okay. Give the temporary to the caller as the final result + *dst_vec = tmp; + return true; +} +#endif // VecCopyElement + +#ifndef mlib_vec_foreach +#define mlib_vec_foreach(Type, VarName, Vector) \ + for (Type *VarName = (Vector).data; VarName && (VarName != (Vector).data + (Vector).size); ++VarName) +#endif + +#ifndef mlib_vec_at +/** + * @brief Obtain a vector element at some zero-based index offset, with negative index + * wrapping (-1 refers to the last element in the vector) + * + * @note The `Vec` argument will be evaluated at least twice! + */ +#define mlib_vec_at(Vec, Pos) ((Vec).data[_mlib_vec_index_adjust((Vec).size, mlib_upsize_integer(Pos))]) +static inline size_t +_mlib_vec_index_adjust(size_t size, mlib_upsized_integer pos) +{ + if (pos.is_signed && pos.bits.as_signed < 0) { + return mlib_assert_add(size_t, size, pos.bits.as_signed); + } + mlib_check(pos.bits.as_unsigned, lte, size, because, "the vector index must be in-bounds for mlib_vec_at()"); + return pos.bits.as_unsigned; +} +#endif + +mlib_extern_c_end(); + +#undef T +#undef VecName +#undef VecDestroyElement +#undef VecInitElement +#undef VecTrivialCopyElement +#ifdef VecCopyElement +#undef VecCopyElement +#endif +// These ones we want to pop, not undefine: +#pragma pop_macro("fn") +#pragma pop_macro("vec_inline_spec") + +// vi: ft=c diff --git a/src/common/tests/test-mlib.c b/src/common/tests/test-mlib.c index dbf570a182b..b0e8816125a 100644 --- a/src/common/tests/test-mlib.c +++ b/src/common/tests/test-mlib.c @@ -75,6 +75,9 @@ _test_checks(void) mlib_assert_aborts () { mlib_check(3, gte, 5); } + + // An infix with a reason string + mlib_check(1, eq, 1, because, "1 = 1"); } static void @@ -917,6 +920,135 @@ _test_str_view(void) // But "Food" > "foo" when case-insensitive: mlib_check(mstr_latin_casecmp(mstr_cstring("Food"), >, mstr_cstring("foo"))); } + + // Trimming + { + mstr_view s = mstr_cstring(" foo bar \n"); + mlib_check(mstr_cmp(mstr_trim_left(s), ==, mstr_cstring("foo bar \n"))); + mlib_check(mstr_cmp(mstr_trim_right(s), ==, mstr_cstring(" foo bar"))); + mlib_check(mstr_cmp(mstr_trim(s), ==, mstr_cstring("foo bar"))); + } +} + +static inline void +_test_str(void) +{ + // Simple empty + { + mstr s = mstr_new(0); + // Length is zero + mlib_check(s.len, eq, 0); + // Data is not null for empty strings, since we want a null terminator + mlib_check(s.data != NULL); + // The null terminator is present: + mlib_check(s.data[0], eq, 0); + mstr_destroy(&s); + } + + // Simple copy of a C string + { + mstr s = mstr_copy_cstring("foo bar"); + mlib_check(s.len, eq, 7); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foo bar"))); + mstr_destroy(&s); + } + + // Concat two strings + { + mstr s = mstr_concat(mstr_cstring("foo"), mstr_cstring("bar")); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foobar"))); + mstr_destroy(&s); + } + + // Append individual characters + { + mstr s = mstr_new(0); + mstr_append_char(&s, 'f'); + mstr_append_char(&s, 'o'); + mstr_append_char(&s, 'o'); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foo"))); + mstr_destroy(&s); + } + + // Splice deletion + { + mstr s = mstr_copy_cstring("foo bar baz"); + mlib_check(mstr_splice(&s, 4, 3, mstr_cstring(""))); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foo baz"))); + + mstr_assign(&s, mstr_cstring("foo bar baz")); + mlib_check(mstr_splice(&s, 4, 3, mstr_cstring("quux"))); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foo quux baz"))); + + mstr_assign(&s, mstr_cstring("foo bar baz")); + mlib_check(mstr_splice(&s, 4, 0, mstr_cstring("quux "))); + mlib_check(mstr_cmp(s, ==, mstr_cstring("foo quux bar baz"))); + + mstr_destroy(&s); + } + + // Replacing + { + mstr s = mstr_copy_cstring("abcd abcd"); + mlib_check(mstr_replace(&s, mstr_cstring("b"), mstr_cstring("foo"))); + mlib_check(mstr_cmp(s, ==, mstr_cstring("afoocd afoocd"))); + + // Try to replace where the replacement contains the needle + mstr_assign(&s, mstr_cstring("foo bar baz")); + mlib_check(mstr_replace(&s, mstr_cstring("bar"), mstr_cstring("foo bar baz"))); + // A naive impl would explode into an infinite string, but we don't try to replace + // within the already-replaced content: + mlib_check(s.data, str_eq, "foo foo bar baz baz"); + + // Try to replace, where the needle is an empty string. + mstr_assign(&s, mstr_cstring("foo")); + mlib_check(mstr_replace(&s, mstr_cstring(""), mstr_cstring("bar"))); + mlib_check(s.data, str_eq, "barfbarobarobar"); + + mstr_assign(&s, mstr_cstring("foofoofoo")); + mlib_check(mstr_replace(&s, mstr_cstring("foo"), mstr_cstring("bar"))); + mlib_check(s.data, str_eq, "barbarbar"); + + mstr_destroy(&s); + } + + // Self-assignment/insertion + { + // Use `assign()` over itself + mstr s = mstr_copy_cstring("foo bar baz"); + mstr_assign(&s, s); + mlib_check(s.data, str_eq, "foo bar baz"); + + // Use splice() where the insertion string overlaps the target + mstr_view bar = mstr_substr(s, 4, 3); + mlib_check(mstr_splice(&s, 0, 3, bar)); + mlib_check(mstr_splice(&s, 8, 3, bar)); + mlib_check(s.data, str_eq, "bar bar bar"); + + // Use replace() with a needle that points into the target + mstr_replace(&s, bar, mstr_cstring("foo")); + mlib_check(s.data, str_eq, "foo foo foo"); + + mstr_destroy(&s); + } +} + +static void +_test_str_format(void) +{ + mstr s = mstr_sprintf("foo"); + mlib_check(s.len, eq, 3); + mlib_check(s.data, str_eq, "foo"); + mstr_sprintf_append(&s, " bar"); + mlib_check(s.data, str_eq, "foo bar"); + mstr_sprintf_append(&s, " %d", 123); + mlib_check(s.data, str_eq, "foo bar 123"); + + // Attempt to format into itself: + mstr_sprintf_append(&s, " hey %s", s.data); + mlib_check(s.data, str_eq, "foo bar 123 hey foo bar 123"); + + mstr_destroy(&s); } static void @@ -1119,6 +1251,92 @@ _test_timer(void) mlib_check(mlib_timer_is_expired(tm)); } +// Tests for `int_vec` assert the behavior of the vector type when handling trivial +// elements. +#define T int +#include +static void +_test_int_vec(void) +{ + int_vec ints = int_vec_new(); + mlib_check(ints.size, eq, 0, because, "Initial vector is empty"); + + // Append an element + int *el; + mlib_check((el = int_vec_push(&ints))); + *el = 42; + mlib_check(int_vec_begin(&ints)[0], eq, 42); + mlib_check(ints.size, eq, 1); + + int_vec_erase_at(&ints, 0); + mlib_check(ints.size, eq, 0, because, "We are back to an empty vector"); + + *int_vec_push(&ints) = 42; + *int_vec_push(&ints) = 1729; + *int_vec_push(&ints) = 123456; + *int_vec_push(&ints) = -7; + mlib_check(ints.size, eq, 4, because, "We added four elements from empty"); + mlib_check(mlib_vec_at(ints, -1), eq, -7, because, "Negative index wraps"); + + // Erase in the middle + int_vec_erase(&ints, ints.data + 1, ints.data + 3); + mlib_check(ints.size, eq, 2, because, "We erased two elements"); + mlib_check(mlib_vec_at(ints, 1), eq, -7, because, "We erased, so the back elements shifted down"); + mlib_check(mlib_vec_at(ints, -1), eq, -7, because, "-7 is still the last element"); + + int_vec_destroy(&ints); +} + +#define T char * +#define VecName cstring_vec +#define VecDestroyElement(CStrPtr) ((free(*CStrPtr), *CStrPtr = NULL)) +#define VecCopyElement(Dst, Src) ((*Dst = strdup(*Src))) +#include +static void +_test_cstring_vec(void) +{ + // Simple new and destroy + { + cstring_vec v = cstring_vec_new(); + mlib_check(v.size, eq, 0); + mlib_check(v.capacity, eq, 0); + cstring_vec_destroy(&v); + } + // Simple new and push an element + { + cstring_vec v = cstring_vec_new(); + *cstring_vec_push(&v) = strdup("Hey"); + mlib_check(v.size, eq, 1); + mlib_check(v.capacity, eq, 1); + mlib_check(cstring_vec_begin(&v)[0], str_eq, "Hey"); + cstring_vec_destroy(&v); + } + // Copy an empty + { + cstring_vec v = cstring_vec_new(); + cstring_vec b; + cstring_vec_init_copy(&b, &v); + cstring_vec_destroy(&v); + cstring_vec_destroy(&b); + } + // Copy non-empty + { + cstring_vec a = cstring_vec_new(); + *cstring_vec_push(&a) = strdup("Hello"); + *cstring_vec_push(&a) = strdup("world!"); + mlib_check(a.size, eq, 2); + mlib_check(a.capacity, eq, 2); + cstring_vec b; + mlib_check(cstring_vec_init_copy(&b, &a)); + mlib_check(a.size, eq, 2); + mlib_check(a.capacity, eq, 2); + mlib_check(cstring_vec_begin(&a)[0], str_eq, "Hello"); + mlib_check(cstring_vec_begin(&b)[1], str_eq, "world!"); + cstring_vec_destroy(&b); + cstring_vec_destroy(&a); + } +} + void test_mlib_install(TestSuite *suite) { @@ -1135,10 +1353,14 @@ test_mlib_install(TestSuite *suite) TestSuite_Add(suite, "/mlib/check-cast", _test_cast); TestSuite_Add(suite, "/mlib/ckdint-partial", _test_ckdint_partial); TestSuite_Add(suite, "/mlib/str_view", _test_str_view); + TestSuite_Add(suite, "/mlib/str", _test_str); + TestSuite_Add(suite, "/mlib/str-format", _test_str_format); TestSuite_Add(suite, "/mlib/duration", _test_duration); TestSuite_Add(suite, "/mlib/time_point", _test_time_point); TestSuite_Add(suite, "/mlib/sleep", _test_sleep); TestSuite_Add(suite, "/mlib/timer", _test_timer); + TestSuite_Add(suite, "/mlib/int-vector", _test_int_vec); + TestSuite_Add(suite, "/mlib/string-vector", _test_cstring_vec); } mlib_diagnostic_pop(); diff --git a/src/libmongoc/src/mongoc/mongoc-openssl-private.h b/src/libmongoc/src/mongoc/mongoc-openssl-private.h index 9560b187a52..f4f41864aa4 100644 --- a/src/libmongoc/src/mongoc/mongoc-openssl-private.h +++ b/src/libmongoc/src/mongoc/mongoc-openssl-private.h @@ -55,5 +55,4 @@ _mongoc_tlsfeature_has_status_request(const uint8_t *data, int length); BSON_END_DECLS - #endif /* MONGOC_OPENSSL_PRIVATE_H */ diff --git a/src/libmongoc/tests/TestSuite.c b/src/libmongoc/tests/TestSuite.c index c82bc338361..82c2ed4b50d 100644 --- a/src/libmongoc/tests/TestSuite.c +++ b/src/libmongoc/tests/TestSuite.c @@ -20,6 +20,9 @@ #include #include +#include + +#include #include @@ -131,9 +134,6 @@ TestSuite_Init(TestSuite *suite, const char *name, int argc, char **argv) suite->flags = 0; suite->prgname = bson_strdup(argv[0]); suite->silent = false; - suite->ctest_run = NULL; - _mongoc_array_init(&suite->match_patterns, sizeof(char *)); - _mongoc_array_init(&suite->failing_flaky_skips, sizeof(TestSkip *)); for (i = 1; i < argc; i++) { if (0 == strcmp("-d", argv[i])) { @@ -169,10 +169,12 @@ TestSuite_Init(TestSuite *suite, const char *name, int argc, char **argv) suite->flags |= TEST_HELPTEXT; } else if (0 == strcmp("--list-tests", argv[i])) { suite->flags |= TEST_LISTTESTS; + } else if (0 == strcmp("--tests-cmake", argv[i])) { + suite->flags |= TEST_TESTS_CMAKE; } else if ((0 == strcmp("-s", argv[i])) || (0 == strcmp("--silent", argv[i]))) { suite->silent = true; } else if ((0 == strcmp("--ctest-run", argv[i]))) { - if (suite->ctest_run) { + if (suite->ctest_run.data) { test_error("'--ctest-run' can only be specified once"); } if (argc - 1 == i) { @@ -180,14 +182,14 @@ TestSuite_Init(TestSuite *suite, const char *name, int argc, char **argv) } suite->flags |= TEST_NOFORK; suite->silent = true; - suite->ctest_run = bson_strdup(argv[++i]); + suite->ctest_run = mstr_copy_cstring(argv[i + 1]); + ++i; } else if ((0 == strcmp("-l", argv[i])) || (0 == strcmp("--match", argv[i]))) { - char *val; if (argc - 1 == i) { test_error("%s requires an argument.", argv[i]); } - val = bson_strdup(argv[++i]); - _mongoc_array_append_val(&suite->match_patterns, val); + ++i; + *mstr_vec_push(&suite->match_patterns) = mstr_copy_cstring(argv[i]); } else if (0 == strcmp("--skip-tests", argv[i])) { if (argc - 1 == i) { test_error("%s requires an argument.", argv[i]); @@ -201,7 +203,7 @@ TestSuite_Init(TestSuite *suite, const char *name, int argc, char **argv) } } - if (suite->match_patterns.len != 0 && suite->ctest_run != NULL) { + if (suite->match_patterns.size != 0 && suite->ctest_run.data) { test_error("'--ctest-run' cannot be specified with '-l' or '--match'"); } @@ -276,61 +278,55 @@ TestSuite_AddLive(TestSuite *suite, /* IN */ const char *name, /* IN */ TestFunc func) /* IN */ { - TestSuite_AddFullWithTestFn(suite, name, TestSuite_AddHelper, NULL, func, TestSuite_CheckLive); -} - - -static void -_TestSuite_AddCheck(Test *test, CheckFunc check, const char *name) -{ - test->checks[test->num_checks] = check; - if (++test->num_checks > MAX_TEST_CHECK_FUNCS) { - MONGOC_STDERR_PRINTF("Too many check funcs for %s, increase MAX_TEST_CHECK_FUNCS " - "to more than %d\n", - name, - MAX_TEST_CHECK_FUNCS); - abort(); - } + // Add the `lock:live-server` tag to the test. + mstr with_tags = mstr_sprintf("%s [lock:live-server]", name); + TestSuite_AddFullWithTestFn(suite, with_tags.data, TestSuite_AddHelper, NULL, func, TestSuite_CheckLive); + mstr_destroy(&with_tags); } Test * -_V_TestSuite_AddFull(TestSuite *suite, const char *name, TestFuncWC func, TestFuncDtor dtor, void *ctx, va_list ap) +_V_TestSuite_AddFull( + TestSuite *suite, const char *name_and_tags, TestFuncWC func, TestFuncDtor dtor, void *ctx, va_list ap) { - CheckFunc check; - Test *test; - Test *iter; - - if (suite->ctest_run && (0 != strcmp(suite->ctest_run, name))) { + // Split the name and tags around the first whitespace: + mstr_view name, tags; + mstr_split_around(mstr_cstring(name_and_tags), mstr_cstring(" "), &name, &tags); + // Trim extras: + tags = mstr_trim(tags); + + if (suite->ctest_run.data && mstr_cmp(suite->ctest_run, !=, name)) { + // We are running CTest, and not running this particular test, so just skip registering it if (dtor) { dtor(ctx); } return NULL; } - test = (Test *)bson_malloc0(sizeof *test); - test->name = bson_strdup(name); + Test *test = TestVec_push(&suite->tests); + test->name = mstr_copy(name); test->func = func; - test->num_checks = 0; + mstr_view tag, tail; + tail = tags; + while (tail.len) { + mlib_check(mstr_split_around(tail, mstr_cstring("["), NULL, &tag), + because, + "Invalid test specifier: Expected an opening bracket (following whitespace or closing bracket) for a " + "test tag"); + mlib_check( + mstr_split_around(tag, mstr_cstring("]"), &tag, &tail), because, "Expected a closing bracket for test tag"); + *mstr_vec_push(&test->tags) = mstr_copy(tag); + } + + CheckFunc check; while ((check = va_arg(ap, CheckFunc))) { - _TestSuite_AddCheck(test, check, name); + *CheckFuncVec_push(&test->checks) = check; } - test->next = NULL; test->dtor = dtor; test->ctx = ctx; TestSuite_SeedRand(suite, test); - - if (!suite->tests) { - suite->tests = test; - return test; - } - - for (iter = suite->tests; iter->next; iter = iter->next) { - } - - iter->next = test; return test; } @@ -348,7 +344,7 @@ _TestSuite_AddMockServerTest(TestSuite *suite, const char *name, TestFunc func, va_end(ap); if (test) { - _TestSuite_AddCheck(test, TestSuite_CheckMockServerAllowed, name); + *CheckFuncVec_push(&test->checks) = TestSuite_CheckMockServerAllowed; } } @@ -364,13 +360,12 @@ TestSuite_AddWC(TestSuite *suite, /* IN */ } -void -_TestSuite_AddFull(TestSuite *suite, /* IN */ - const char *name, /* IN */ - TestFuncWC func, /* IN */ - TestFuncDtor dtor, /* IN */ - void *ctx, - ...) /* IN */ +void(TestSuite_AddFull)(TestSuite *suite, /* IN */ + const char *name, /* IN */ + TestFuncWC func, /* IN */ + TestFuncDtor dtor, /* IN */ + void *ctx, + ...) /* IN */ { va_list ap; @@ -416,7 +411,7 @@ TestSuite_RunFuncInChild(TestSuite *suite, /* IN */ si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - cmdline = bson_strdup_printf("%s --silent --no-fork -l %s", suite->prgname, test->name); + cmdline = bson_strdup_printf("%s --silent --no-fork -l %.*s", suite->prgname, MSTR_FMT(test->name)); if (!CreateProcess(NULL, cmdline, @@ -490,14 +485,14 @@ TestSuite_RunFuncInChild(TestSuite *suite, /* IN */ dup2(pipefd[1], STDOUT_FILENO); close(pipefd[0]); close(pipefd[1]); - execle(suite->prgname, suite->prgname, "--no-fork", "--silent", "-l", test->name, (char *)0, envp); + execle(suite->prgname, suite->prgname, "--no-fork", "--silent", "-l", test->name.data, (char *)0, envp); } else { /* suppress child output */ fd = open("/dev/null", O_WRONLY); dup2(fd, STDOUT_FILENO); close(fd); - execl(suite->prgname, suite->prgname, "--no-fork", "-l", test->name, (char *)0); + execl(suite->prgname, suite->prgname, "--no-fork", "-l", test->name.data, (char *)0); } exit(-1); @@ -531,10 +526,9 @@ TestSuite_RunTest(TestSuite *suite, /* IN */ char name[MAX_TEST_NAME_LENGTH]; mcommon_string_append_t buf; mcommon_string_t *mock_server_log_buf; - size_t i; int status = 0; - bson_snprintf(name, sizeof name, "%s%s", suite->name, test->name); + bson_snprintf(name, sizeof name, "%s%.*s", suite->name, MSTR_FMT(test->name)); mcommon_string_new_as_append(&buf); @@ -542,19 +536,18 @@ TestSuite_RunTest(TestSuite *suite, /* IN */ test_msg("Begin %s, seed %u", name, test->seed); } - for (i = 0; i < suite->failing_flaky_skips.len; i++) { - TestSkip *skip = _mongoc_array_index(&suite->failing_flaky_skips, TestSkip *, i); - if (0 == strcmp(name, skip->test_name) && skip->subtest_desc == NULL) { - if (suite->ctest_run) { + mlib_vec_foreach (TestSkip, skip, suite->failing_flaky_skips) { + if (mstr_cmp(skip->test_name, ==, mstr_cstring(name)) && !skip->subtest_desc.data) { + if (suite->ctest_run.data) { /* Write a marker that tells CTest that we are skipping this test */ test_msg("@@ctest-skipped@@"); } if (!suite->silent) { mcommon_string_append_printf(&buf, - " { \"status\": \"skip\", \"test_file\": \"%s\"," - " \"reason\": \"%s\" }%s", - test->name, - skip->reason, + " { \"status\": \"skip\", \"test_file\": \"%.*s\"," + " \"reason\": \"%.*s\" }%s", + MSTR_FMT(test->name), + MSTR_FMT(skip->reason), ((*count) == 1) ? "" : ","); test_msg("%s", mcommon_str_from_append(&buf)); if (suite->outfile) { @@ -567,15 +560,17 @@ TestSuite_RunTest(TestSuite *suite, /* IN */ } } - for (i = 0; i < test->num_checks; i++) { - if (!test->checks[i]()) { - if (suite->ctest_run) { + mlib_vec_foreach (CheckFunc, check, test->checks) { + if (!(*check)()) { + if (suite->ctest_run.data) { /* Write a marker that tells CTest that we are skipping this test */ test_msg("@@ctest-skipped@@"); } if (!suite->silent) { - mcommon_string_append_printf( - &buf, " { \"status\": \"skip\", \"test_file\": \"%s\" }%s", test->name, ((*count) == 1) ? "" : ","); + mcommon_string_append_printf(&buf, + " { \"status\": \"skip\", \"test_file\": \"%.*s\" }%s", + MSTR_FMT(test->name), + ((*count) == 1) ? "" : ","); test_msg("%s", mcommon_str_from_append(&buf)); if (suite->outfile) { fprintf(suite->outfile, "%s", mcommon_str_from_append(&buf)); @@ -670,6 +665,7 @@ TestSuite_PrintHelp(TestSuite *suite) /* IN */ "Options:\n" " -h, --help Show this help menu.\n" " --list-tests Print list of available tests.\n" + " --tests-cmake Print CMake code that defines test information.\n" " -f, --no-fork Do not spawn a process per test (abort on " "first error).\n" " -l, --match PATTERN Run test by name, e.g. \"/Client/command\" or " @@ -690,16 +686,26 @@ TestSuite_PrintHelp(TestSuite *suite) /* IN */ static void TestSuite_PrintTests(TestSuite *suite) /* IN */ { - Test *iter; - printf("\nTests:\n"); - for (iter = suite->tests; iter; iter = iter->next) { - printf("%s%s\n", suite->name, iter->name); + mlib_vec_foreach (Test, t, suite->tests) { + printf("%s%.*s\n", suite->name, MSTR_FMT(t->name)); } printf("\n"); } +static void +TestSuite_PrintCMake(TestSuite *suite) +{ + printf("set(MONGOC_TESTS)\n"); + mlib_vec_foreach (Test, t, suite->tests) { + printf("list(APPEND MONGOC_TESTS [[%.*s]])\n", MSTR_FMT(t->name)); + printf("set(MONGOC_TEST_%.*s_TAGS)\n", MSTR_FMT(t->name)); + mlib_vec_foreach (mstr, tag, t->tags) { + printf("list(APPEND MONGOC_TEST_%.*s_TAGS [[%.*s]])\n", MSTR_FMT(t->name), MSTR_FMT(*tag)); + } + } +} static void TestSuite_PrintJsonSystemHeader(FILE *stream) @@ -870,7 +876,7 @@ TestSuite_TestMatchesName(const TestSuite *suite, const Test *test, const char * char name[128]; bool star = strlen(testname) && testname[strlen(testname) - 1] == '*'; - bson_snprintf(name, sizeof name, "%s%s", suite->name, test->name); + bson_snprintf(name, sizeof name, "%s%.*s", suite->name, MSTR_FMT(test->name)); if (star) { /* e.g. testname is "/Client*" and name is "/Client/authenticate" */ @@ -884,19 +890,18 @@ TestSuite_TestMatchesName(const TestSuite *suite, const Test *test, const char * bool test_matches(TestSuite *suite, Test *test) { - if (suite->ctest_run) { + if (suite->ctest_run.data) { /* We only want exactly the named test */ - return strcmp(test->name, suite->ctest_run) == 0; + return mstr_cmp(test->name, ==, suite->ctest_run); } /* If no match patterns were provided, then assume all match. */ - if (suite->match_patterns.len == 0) { + if (suite->match_patterns.size == 0) { return true; } - for (size_t i = 0u; i < suite->match_patterns.len; i++) { - char *pattern = _mongoc_array_index(&suite->match_patterns, char *, i); - if (TestSuite_TestMatchesName(suite, test, pattern)) { + mlib_vec_foreach (mstr, pat, suite->match_patterns) { + if (TestSuite_TestMatchesName(suite, test, pat->data)) { return true; } } @@ -905,23 +910,9 @@ test_matches(TestSuite *suite, Test *test) } void -_process_skip_file(const char *filename, mongoc_array_t *skips) +_process_skip_file(const char *filename, TestSkipVec *skips) { - const int max_lines = 1000; - int lines_read = 0; - char buffer[SKIP_LINE_BUFFER_SIZE]; - size_t buflen; FILE *skip_file; - char *fgets_ret; - TestSkip *skip; - char *test_name_end; - size_t comment_len; - char *comment_char; - char *comment_text; - size_t subtest_len; - size_t new_buflen; - char *subtest_start; - char *subtest_end; #ifdef _WIN32 if (0 != fopen_s(&skip_file, filename, "r")) { @@ -934,73 +925,47 @@ _process_skip_file(const char *filename, mongoc_array_t *skips) test_error("Failed to open skip file: %s: errno: %d", filename, errno); } - while (lines_read < max_lines) { - fgets_ret = fgets(buffer, sizeof(buffer), skip_file); - buflen = strlen(buffer); - - if (buflen == 0 || !fgets_ret) { - break; /* error or EOF */ + while (1) { + char buffer[SKIP_LINE_BUFFER_SIZE]; + if (!fgets(buffer, sizeof(buffer), skip_file)) { + break; /* error */ } - if (buffer[0] == '#' || buffer[0] == ' ' || buffer[0] == '\n') { - continue; /* Comment line or blank line */ + mstr_view line = mstr_cstring(buffer); + if (!line.len) { + // EOF + break; } - - skip = (TestSkip *)bson_malloc0(sizeof *skip); - if (buffer[buflen - 1] == '\n') - buflen--; - test_name_end = buffer + buflen; - - /* First get the comment, starting at '#' to EOL */ - comment_len = 0; - comment_char = strchr(buffer, '#'); - if (comment_char) { - test_name_end = comment_char; - comment_text = comment_char; - while (comment_text[0] == '#' || comment_text[0] == ' ' || comment_text[0] == '\t') { - if (++comment_text >= (buffer + buflen)) - break; - } - skip->reason = bson_strndup(comment_text, buflen - (comment_text - buffer)); - comment_len = buflen - (comment_char - buffer); - } else { - skip->reason = NULL; + // Remove whitespace + line = mstr_trim(line); + if (line.len == 0 || line.data[0] == '#') { + // Empty line or comment + continue; } - /* Next get the subtest name, from first '"' until last '"' */ - new_buflen = buflen - comment_len; - subtest_start = strstr(buffer, "/\""); - if (subtest_start && (!comment_char || (subtest_start < comment_char))) { - test_name_end = subtest_start; - subtest_start++; - /* find the second '"' that marks end of subtest name */ - subtest_end = subtest_start + 1; - while (subtest_end[0] != '\0' && subtest_end[0] != '"' && (subtest_end < buffer + new_buflen)) { - subtest_end++; - } - /* 'subtest_start + 1' to trim leading and trailing '"' */ - subtest_len = subtest_end - (subtest_start + 1); - skip->subtest_desc = bson_strndup(subtest_start + 1, subtest_len); - } else { - skip->subtest_desc = NULL; - } + TestSkip skip = {0}; + // If there is a trailing comment, drop that: + mstr_view comment = {0}; + mstr_split_around(line, mstr_cstring("#"), &line, &comment); + line = mstr_trim(line); + comment = mstr_trim(comment); - /* Next get the test name */ - while (test_name_end[-1] == ' ' && test_name_end > buffer) { - /* trailing space might be between test name and '#' */ - test_name_end--; + if (comment.len) { + skip.reason = mstr_copy(comment); } - skip->test_name = bson_strndup(buffer, test_name_end - buffer); - _mongoc_array_append_val(skips, skip); - - lines_read++; - } - if (lines_read == max_lines) { - test_error("Skip file: %s exceeded maximum lines: %d. Increase " - "max_lines in _process_skip_file", - filename, - max_lines); + // If it contains a '/"' substring, the quoted part is the subtest description, + // and everything before the '/' is the main test name. Split on that: + mstr_view test_name; + mstr_view subtest_desc; + if (mstr_split_around(line, mstr_cstring("/\""), &test_name, &subtest_desc)) { + // Drop trailing quote: + mlib_check(mstr_at(subtest_desc, -1), eq, '"', because, "Subtest description should end with a quote"); + subtest_desc = mstr_slice(subtest_desc, 0, -1); + skip.subtest_desc = mstr_copy(subtest_desc); + } + skip.test_name = mstr_copy(test_name); + *TestSkipVec_push(skips) = skip; } fclose(skip_file); } @@ -1008,30 +973,29 @@ _process_skip_file(const char *filename, mongoc_array_t *skips) static int TestSuite_RunAll(TestSuite *suite /* IN */) { - Test *test; int count = 0; int status = 0; ASSERT(suite); /* initialize "count" so we can omit comma after last test output */ - for (test = suite->tests; test; test = test->next) { - if (test_matches(suite, test)) { + mlib_vec_foreach (Test, t, suite->tests) { + if (test_matches(suite, t)) { count++; } } - if (suite->ctest_run) { + if (suite->ctest_run.data) { /* We should have matched *at most* one test */ ASSERT(count <= 1); if (count == 0) { - test_error("No such test '%s'", suite->ctest_run); + test_error("No such test '%.*s'", MSTR_FMT(suite->ctest_run)); } } - for (test = suite->tests; test; test = test->next) { - if (test_matches(suite, test)) { - status += TestSuite_RunTest(suite, test, &count); + mlib_vec_foreach (Test, t, suite->tests) { + if (test_matches(suite, t)) { + status += TestSuite_RunTest(suite, t, &count); count--; } } @@ -1063,7 +1027,11 @@ TestSuite_Run(TestSuite *suite) /* IN */ TestSuite_PrintTests(suite); } - if ((suite->flags & TEST_HELPTEXT) || (suite->flags & TEST_LISTTESTS)) { + if (suite->flags & TEST_TESTS_CMAKE) { + TestSuite_PrintCMake(suite); + } + + if ((suite->flags & TEST_HELPTEXT) || (suite->flags & TEST_LISTTESTS) || (suite->flags & TEST_TESTS_CMAKE)) { return 0; } @@ -1075,39 +1043,20 @@ TestSuite_Run(TestSuite *suite) /* IN */ } start_us = bson_get_monotonic_time(); - if (suite->tests) { - failures += TestSuite_RunAll(suite); - } else if (!suite->silent) { - TestSuite_PrintJsonFooter(stdout); - if (suite->outfile) { - TestSuite_PrintJsonFooter(suite->outfile); - } - } + failures += TestSuite_RunAll(suite); MONGOC_DEBUG("Duration of all tests (s): %" PRId64, (bson_get_monotonic_time() - start_us) / (1000 * 1000)); return failures; } - void TestSuite_Destroy(TestSuite *suite) { - Test *test; - Test *tmp; - bson_mutex_lock(&gTestMutex); gTestSuite = NULL; bson_mutex_unlock(&gTestMutex); - for (test = suite->tests; test; test = tmp) { - tmp = test->next; - - if (test->dtor) { - test->dtor(test->ctx); - } - bson_free(test->name); - bson_free(test); - } + TestVec_destroy(&suite->tests); if (suite->outfile) { fclose(suite->outfile); @@ -1117,23 +1066,9 @@ TestSuite_Destroy(TestSuite *suite) bson_free(suite->name); bson_free(suite->prgname); - bson_free(suite->ctest_run); - for (size_t i = 0u; i < suite->match_patterns.len; i++) { - char *val = _mongoc_array_index(&suite->match_patterns, char *, i); - bson_free(val); - } - - _mongoc_array_destroy(&suite->match_patterns); - - for (size_t i = 0u; i < suite->failing_flaky_skips.len; i++) { - TestSkip *val = _mongoc_array_index(&suite->failing_flaky_skips, TestSkip *, i); - bson_free(val->test_name); - bson_free(val->subtest_desc); - bson_free(val->reason); - bson_free(val); - } - - _mongoc_array_destroy(&suite->failing_flaky_skips); + mstr_destroy(&suite->ctest_run); + mstr_vec_destroy(&suite->match_patterns); + TestSkipVec_destroy(&suite->failing_flaky_skips); } diff --git a/src/libmongoc/tests/TestSuite.h b/src/libmongoc/tests/TestSuite.h index c3627c71e40..ea2e1176c45 100644 --- a/src/libmongoc/tests/TestSuite.h +++ b/src/libmongoc/tests/TestSuite.h @@ -25,6 +25,8 @@ #include +#include +#include #include #include @@ -94,6 +96,7 @@ bson_open(const char *filename, int flags, ...) #define TEST_DEBUGOUTPUT (1 << 3) #define TEST_TRACE (1 << 4) #define TEST_LISTTESTS (1 << 5) +#define TEST_TESTS_CMAKE (1 << 6) #define CERT_CA CERT_TEST_DIR "/ca.pem" @@ -655,37 +658,110 @@ typedef void (*TestFunc)(void); typedef void (*TestFuncWC)(void *); typedef void (*TestFuncDtor)(void *); typedef int (*CheckFunc)(void); -typedef struct _Test Test; -typedef struct _TestSuite TestSuite; +typedef struct Test Test; +typedef struct TestSuite TestSuite; typedef struct _TestFnCtx TestFnCtx; -typedef struct _TestSkip TestSkip; - - -struct _Test { - Test *next; - char *name; +typedef struct TestSkip TestSkip; + +#define T CheckFunc +#define VecName CheckFuncVec +#include + +struct Test { + /** + * @brief The C string that names the test case + */ + mstr name; + /** + * @brief Set of tags that are associated with this test case + */ + mstr_vec tags; + /** + * @brief The function that will be executed for the test case + */ TestFuncWC func; + /** + * @brief The function that destroys the context data associated with the test case + */ TestFuncDtor dtor; + /** + * @brief Pointer to arbitrary context data associated with the text case + */ void *ctx; + /** + * @brief The exit code that was received from the test function + */ int exit_code; + /** + * @brief Randomness seed for the test case + */ unsigned seed; - CheckFunc checks[MAX_TEST_CHECK_FUNCS]; - size_t num_checks; + /** + * @brief Array of check functions that determine whether this test case should be skipped + */ + CheckFuncVec checks; }; +static inline void +Test_Destroy(Test *t) +{ + if (t->dtor) { + t->dtor(t->ctx); + } + mstr_destroy(&t->name); + mstr_vec_destroy(&t->tags); + CheckFuncVec_destroy(&t->checks); +} + +#define T Test +#define VecName TestVec +#define VecDestroyElement Test_Destroy +#include + +/** + * @brief Information about a test that we plan to skip + */ +struct TestSkip { + /** + * @brief The name of the test that is being skipped + */ + mstr test_name; + /** + * @brief If not-null, the description of the sub-test that we are skipping. + */ + mstr subtest_desc; + /** + * @brief An explanatory string for why we are skipping the test + */ + mstr reason; +}; -struct _TestSuite { +static inline void +TestSkip_Destroy(TestSkip *skip) +{ + mstr_destroy(&skip->test_name); + mstr_destroy(&skip->subtest_desc); + mstr_destroy(&skip->reason); +} + +#define T TestSkip +#define VecName TestSkipVec +#define VecDestroyElement(Skip) TestSkip_Destroy(Skip) +#include + + +struct TestSuite { char *prgname; char *name; - mongoc_array_t match_patterns; - char *ctest_run; - Test *tests; + mstr_vec match_patterns; + mstr ctest_run; + TestVec tests; FILE *outfile; int flags; int silent; mcommon_string_t *mock_server_log_buf; FILE *mock_server_log; - mongoc_array_t failing_flaky_skips; + TestSkipVec failing_flaky_skips; }; @@ -694,18 +770,10 @@ struct _TestFnCtx { TestFuncDtor dtor; }; - -struct _TestSkip { - char *test_name; - char *subtest_desc; - char *reason; -}; - - void TestSuite_Init(TestSuite *suite, const char *name, int argc, char **argv); void -TestSuite_Add(TestSuite *suite, const char *name, TestFunc func); +TestSuite_Add(TestSuite *suite, const char *name_and_tags, TestFunc func); int TestSuite_CheckLive(void); void @@ -716,21 +784,22 @@ void _TestSuite_AddMockServerTest(TestSuite *suite, const char *name, TestFunc func, ...); #define TestSuite_AddMockServerTest(_suite, _name, ...) _TestSuite_AddMockServerTest(_suite, _name, __VA_ARGS__, NULL) void -TestSuite_AddWC(TestSuite *suite, const char *name, TestFuncWC func, TestFuncDtor dtor, void *ctx); +TestSuite_AddWC(TestSuite *suite, const char *name_and_tags, TestFuncWC func, TestFuncDtor dtor, void *ctx); Test * -_V_TestSuite_AddFull(TestSuite *suite, const char *name, TestFuncWC func, TestFuncDtor dtor, void *ctx, va_list ap); +_V_TestSuite_AddFull( + TestSuite *suite, const char *name_and_tags, TestFuncWC func, TestFuncDtor dtor, void *ctx, va_list ap); void -_TestSuite_AddFull(TestSuite *suite, const char *name, TestFuncWC func, TestFuncDtor dtor, void *ctx, ...); +TestSuite_AddFull(TestSuite *suite, const char *name_and_tags, TestFuncWC func, TestFuncDtor dtor, void *ctx, ...); void _TestSuite_TestFnCtxDtor(void *ctx); #define TestSuite_AddFull(_suite, _name, _func, _dtor, _ctx, ...) \ - _TestSuite_AddFull(_suite, _name, _func, _dtor, _ctx, __VA_ARGS__, NULL) -#define TestSuite_AddFullWithTestFn(_suite, _name, _func, _dtor, _test_fn, ...) \ - do { \ - TestFnCtx *ctx = bson_malloc(sizeof(TestFnCtx)); \ - ctx->test_fn = (TestFunc)(_test_fn); \ - ctx->dtor = _dtor; \ - _TestSuite_AddFull(_suite, _name, _func, _TestSuite_TestFnCtxDtor, ctx, __VA_ARGS__, NULL); \ + (TestSuite_AddFull)(_suite, _name, _func, _dtor, _ctx, __VA_ARGS__, NULL) +#define TestSuite_AddFullWithTestFn(_suite, _name, _func, _dtor, _test_fn, ...) \ + do { \ + TestFnCtx *ctx = bson_malloc(sizeof(TestFnCtx)); \ + ctx->test_fn = (TestFunc)(_test_fn); \ + ctx->dtor = _dtor; \ + TestSuite_AddFull(_suite, _name, _func, _TestSuite_TestFnCtxDtor, ctx, __VA_ARGS__, NULL); \ } while (0) int TestSuite_Run(TestSuite *suite); @@ -742,7 +811,7 @@ test_suite_debug_output(void); void test_suite_mock_server_log(const char *msg, ...); void -_process_skip_file(const char *, mongoc_array_t *); +_process_skip_file(const char *, TestSkipVec *); bool TestSuite_NoFork(TestSuite *suite); diff --git a/src/libmongoc/tests/json-test.c b/src/libmongoc/tests/json-test.c index 22e0953e891..46b41cd8b34 100644 --- a/src/libmongoc/tests/json-test.c +++ b/src/libmongoc/tests/json-test.c @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -1884,9 +1885,13 @@ _install_json_test_suite_with_check(TestSuite *suite, const char *base, const ch bson_snprintf(joined, PATH_MAX, "%s/%s", base, subdir); ASSERT(realpath(joined, resolved)); - if (suite->ctest_run) { - const char *found = strstr(suite->ctest_run, subdir); - if (found != suite->ctest_run && found != suite->ctest_run + 1) { + if (suite->ctest_run.data) { + // If we're running a specific test, only register if the directory we are scanning + // is a prefix of the requested test pathname + size_t where = mstr_find(suite->ctest_run, mstr_cstring(subdir)); + // allow where == 0 or where == 1 to allow optional leading slash in the + // test specifier: + if (where > 1) { return; } } @@ -1903,45 +1908,47 @@ _install_json_test_suite_with_check(TestSuite *suite, const char *base, const ch ext[0] = '\0'; test = _skip_if_unsupported(skip_json, test); - for (size_t j = 0u; j < suite->failing_flaky_skips.len; j++) { - TestSkip *skip = _mongoc_array_index(&suite->failing_flaky_skips, TestSkip *, j); - if (0 == strcmp(skip_json, skip->test_name)) { - /* Modify the test file to give applicable entries a skipReason */ - bson_t *modified = bson_new(); - bson_array_builder_t *modified_tests; - bson_iter_t iter; - - bson_copy_to_excluding_noinit(test, modified, "tests", NULL); - BSON_APPEND_ARRAY_BUILDER_BEGIN(modified, "tests", &modified_tests); - BSON_ASSERT(bson_iter_init_find(&iter, test, "tests")); - for (bson_iter_recurse(&iter, &iter); bson_iter_next(&iter);) { - bson_iter_t desc_iter; - uint32_t desc_len; - const char *desc; - bson_t original_test; - bson_t modified_test; - - bson_iter_bson(&iter, &original_test); - bson_iter_init_find(&desc_iter, &original_test, "description"); - desc = bson_iter_utf8(&desc_iter, &desc_len); - - bson_array_builder_append_document_begin(modified_tests, &modified_test); - bson_concat(&modified_test, &original_test); - if (!skip->subtest_desc || 0 == strcmp(skip->subtest_desc, desc)) { - BSON_APPEND_UTF8(&modified_test, "skipReason", skip->reason != NULL ? skip->reason : "(null)"); - } - bson_array_builder_append_document_end(modified_tests, &modified_test); + mlib_vec_foreach (TestSkip, skip, suite->failing_flaky_skips) { + if (mstr_cmp(mstr_cstring(skip_json), !=, skip->test_name)) { + continue; + } + /* Modify the test file to give applicable entries a skipReason */ + bson_t *modified = bson_new(); + bson_array_builder_t *modified_tests; + bson_iter_t iter; + + bson_copy_to_excluding_noinit(test, modified, "tests", NULL); + BSON_APPEND_ARRAY_BUILDER_BEGIN(modified, "tests", &modified_tests); + BSON_ASSERT(bson_iter_init_find(&iter, test, "tests")); + for (bson_iter_recurse(&iter, &iter); bson_iter_next(&iter);) { + bson_iter_t desc_iter; + uint32_t desc_len; + const char *desc; + bson_t original_test; + bson_t modified_test; + + bson_iter_bson(&iter, &original_test); + bson_iter_init_find(&desc_iter, &original_test, "description"); + desc = bson_iter_utf8(&desc_iter, &desc_len); + + bson_array_builder_append_document_begin(modified_tests, &modified_test); + bson_concat(&modified_test, &original_test); + if (!skip->subtest_desc.data || mstr_cmp(skip->subtest_desc, ==, mstr_cstring(desc))) { + BSON_APPEND_UTF8(&modified_test, "skipReason", skip->reason.data ? skip->reason.data : "(null)"); } - bson_append_array_builder_end(modified, modified_tests); - bson_destroy(test); - test = modified; + bson_array_builder_append_document_end(modified_tests, &modified_test); } + bson_append_array_builder_end(modified, modified_tests); + bson_destroy(test); + test = modified; } + mstr name = mstr_copy_cstring(skip_json); + mstr_append(&name, mstr_cstring(" [lock:live-server]")); /* list of "check" functions that decide whether to skip the test */ va_start(ap, callback); - _V_TestSuite_AddFull(suite, skip_json, callback, &bson_destroy_vp, test, ap); - + _V_TestSuite_AddFull(suite, name.data, callback, &bson_destroy_vp, test, ap); va_end(ap); + mstr_destroy(&name); } } diff --git a/src/libmongoc/tests/test-libmongoc.h b/src/libmongoc/tests/test-libmongoc.h index 94017c774d4..550057605e0 100644 --- a/src/libmongoc/tests/test-libmongoc.h +++ b/src/libmongoc/tests/test-libmongoc.h @@ -21,14 +21,14 @@ #include -struct _TestSuite; +struct TestSuite; struct _bson_t; struct _server_version_t; void -test_libmongoc_init(struct _TestSuite *suite, int argc, char **argv); +test_libmongoc_init(struct TestSuite *suite, int argc, char **argv); void -test_libmongoc_destroy(struct _TestSuite *suite); +test_libmongoc_destroy(struct TestSuite *suite); mongoc_database_t * get_test_database(mongoc_client_t *client); diff --git a/src/libmongoc/tests/test-mcd-azure-imds.c b/src/libmongoc/tests/test-mcd-azure-imds.c index e208c9638fa..8cc871796eb 100644 --- a/src/libmongoc/tests/test-mcd-azure-imds.c +++ b/src/libmongoc/tests/test-mcd-azure-imds.c @@ -107,5 +107,10 @@ test_mcd_azure_imds_install(TestSuite *suite) { TestSuite_Add(suite, "/azure/imds/http/parse", _test_oauth_parse); TestSuite_Add(suite, "/azure/imds/http/request", _test_http_req); - TestSuite_AddFull(suite, "/azure/imds/http/talk", _test_with_mock_server, NULL, NULL, have_mock_server_env); + TestSuite_AddFull(suite, + "/azure/imds/http/talk [uses:fake_kms_provider_server][lock:fake-kms]", + _test_with_mock_server, + NULL, + NULL, + have_mock_server_env); } diff --git a/src/libmongoc/tests/test-mongoc-aggregate.c b/src/libmongoc/tests/test-mongoc-aggregate.c index cb6e85ae223..591c22dc049 100644 --- a/src/libmongoc/tests/test-mongoc-aggregate.c +++ b/src/libmongoc/tests/test-mongoc-aggregate.c @@ -175,7 +175,7 @@ test_aggregate_install(TestSuite *suite) { TestSuite_AddMockServerTest(suite, "/Aggregate/query_flags", test_query_flags); TestSuite_AddFull(suite, - "/Aggregate/write_respects_read_prefs", + "/Aggregate/write_respects_read_prefs [lock:live-server]", test_write_respects_read_prefs, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-bulk.c b/src/libmongoc/tests/test-mongoc-bulk.c index 701f89f471b..6fa8e018ce8 100644 --- a/src/libmongoc/tests/test-mongoc-bulk.c +++ b/src/libmongoc/tests/test-mongoc-bulk.c @@ -4897,22 +4897,34 @@ test_bulk_install(TestSuite *suite) TestSuite_AddLive(suite, "/BulkOperation/upsert_ordered", test_upsert_ordered); TestSuite_AddLive(suite, "/BulkOperation/upsert_unordered", test_upsert_unordered); TestSuite_AddFull(suite, - "/BulkOperation/upsert_unordered_oversized", + "/BulkOperation/upsert_unordered_oversized [lock:live-server][timeout:30]", test_upsert_unordered_oversized, NULL, NULL, test_framework_skip_if_slow_or_live); - TestSuite_AddFull( - suite, "/BulkOperation/upsert_large", test_upsert_large, NULL, NULL, test_framework_skip_if_slow_or_live); - TestSuite_AddFull( - suite, "/BulkOperation/upsert_huge", test_upsert_huge, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/BulkOperation/upsert_large [lock:live-server][timeout:30]", + test_upsert_large, + NULL, + NULL, + test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/BulkOperation/upsert_huge [lock:live-server][timeout:30]", + test_upsert_huge, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/BulkOperation/upserted_index_ordered", test_upserted_index_ordered); TestSuite_AddLive(suite, "/BulkOperation/upserted_index_unordered", test_upserted_index_unordered); TestSuite_AddLive(suite, "/BulkOperation/update_one_ordered", test_update_one_ordered); TestSuite_AddLive(suite, "/BulkOperation/update_one_unordered", test_update_one_unordered); TestSuite_AddLive(suite, "/BulkOperation/update_with_opts_validate", test_update_with_opts_validate); - TestSuite_AddFull( - suite, "/BulkOperation/update_arrayfilters", test_update_arrayfilters, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/BulkOperation/update_arrayfilters [lock:live-server]", + test_update_arrayfilters, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddLive(suite, "/BulkOperation/update/hint/validate", test_update_hint_validate); TestSuite_AddLive(suite, "/BulkOperation/delete/hint/validate", test_delete_hint_validate); TestSuite_AddLive(suite, "/BulkOperation/replace_one_ordered", test_replace_one_ordered); @@ -4930,13 +4942,13 @@ test_bulk_install(TestSuite *suite) TestSuite_AddLive(suite, "/BulkOperation/single_unordered_bulk", test_single_unordered_bulk); TestSuite_AddLive(suite, "/BulkOperation/single_error_unordered_bulk", test_single_error_unordered_bulk); TestSuite_AddFull(suite, - "/BulkOperation/oversized/ordered", + "/BulkOperation/oversized/ordered [lock:live-server][timeout:30]", test_oversized_bulk_op_ordered, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/BulkOperation/oversized/unordered", + "/BulkOperation/oversized/unordered [lock:live-server][timeout:30]", test_oversized_bulk_op_unordered, NULL, NULL, @@ -4961,21 +4973,25 @@ test_bulk_install(TestSuite *suite) "/BulkOperation/wtimeout_duplicate_key/write_commands", test_wtimeout_plus_duplicate_key_err_write_commands); TestSuite_AddFull(suite, - "/BulkOperation/large_inserts_ordered", + "/BulkOperation/large_inserts_ordered [lock:live-server][timeout:30]", test_large_inserts_ordered, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/BulkOperation/large_inserts_unordered", + "/BulkOperation/large_inserts_unordered [lock:live-server][timeout:30]", test_large_inserts_unordered, NULL, NULL, test_framework_skip_if_slow_or_live); - TestSuite_AddFull( - suite, "/BulkOperation/numerous_ordered", test_numerous_ordered, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/BulkOperation/numerous_unordered", + "/BulkOperation/numerous_ordered [lock:live-server][timeout:30]", + test_numerous_ordered, + NULL, + NULL, + test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/BulkOperation/numerous_unordered [lock:live-server][timeout:30]", test_numerous_unordered, NULL, NULL, @@ -4986,13 +5002,13 @@ test_bulk_install(TestSuite *suite) TestSuite_AddLive(suite, "/BulkOperation/OP_MSG/max_batch_size", test_bulk_max_batch_size); TestSuite_AddLive(suite, "/BulkOperation/OP_MSG/max_msg_size", test_bulk_max_msg_size); TestSuite_AddFull(suite, - "/BulkOperation/split", + "/BulkOperation/split [lock:live-server]", test_bulk_split, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_no_sessions); TestSuite_AddFull(suite, - "/BulkOperation/write_concern/split", + "/BulkOperation/write_concern/split [lock:live-server]", test_bulk_write_concern_split, NULL /* dtor */, NULL /* ctx */, @@ -5016,7 +5032,7 @@ test_bulk_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/BulkOperation/opts/let", test_bulk_let); TestSuite_AddMockServerTest(suite, "/BulkOperation/opts/let/multi", test_bulk_let_multi); TestSuite_AddFull(suite, - "/BulkOperation/multiple_errors", + "/BulkOperation/multiple_errors [lock:live-server]", test_bulk_write_multiple_errors, NULL, NULL, @@ -5028,7 +5044,7 @@ test_bulk_install(TestSuite *suite) TestSuite_AddLive(suite, "/BulkOperation/multiple_execution", test_multiple_execution); TestSuite_AddFull( suite, - "/BulkOperation/big_let", + "/BulkOperation/big_let [lock:live-server]", test_bulk_big_let, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-bulkwrite.c b/src/libmongoc/tests/test-mongoc-bulkwrite.c index 69cf623d7d4..5accd904200 100644 --- a/src/libmongoc/tests/test-mongoc-bulkwrite.c +++ b/src/libmongoc/tests/test-mongoc-bulkwrite.c @@ -904,7 +904,7 @@ void test_bulkwrite_install(TestSuite *suite) { TestSuite_AddFull(suite, - "/bulkwrite/insert", + "/bulkwrite/insert [lock:live-server]", test_bulkwrite_insert, NULL /* dtor */, NULL /* ctx */, @@ -912,7 +912,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/upsert_with_null", + "/bulkwrite/upsert_with_null [lock:live-server]", test_bulkwrite_upsert_with_null, NULL /* dtor */, NULL /* ctx */, @@ -920,7 +920,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/writeError", + "/bulkwrite/writeError [lock:live-server]", test_bulkwrite_writeError, NULL /* dtor */, NULL /* ctx */, @@ -928,7 +928,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/session_with_unacknowledged", + "/bulkwrite/session_with_unacknowledged [lock:live-server]", test_bulkwrite_session_with_unacknowledged, NULL /* dtor */, NULL /* ctx */, @@ -936,7 +936,7 @@ test_bulkwrite_install(TestSuite *suite) test_framework_skip_if_no_sessions); TestSuite_AddFull(suite, - "/bulkwrite/double_execute", + "/bulkwrite/double_execute [lock:live-server]", test_bulkwrite_double_execute, NULL /* dtor */, NULL /* ctx */, @@ -944,7 +944,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/server_id", + "/bulkwrite/server_id [lock:live-server]", test_bulkwrite_serverid, NULL /* dtor */, NULL /* ctx */, @@ -952,7 +952,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/server_id/unacknowledged", + "/bulkwrite/server_id/unacknowledged [lock:live-server]", test_bulkwrite_serverid_unacknowledged, NULL /* dtor */, NULL /* ctx */, @@ -960,7 +960,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/server_id/on_retry", + "/bulkwrite/server_id/on_retry [lock:live-server]", test_bulkwrite_serverid_on_retry, NULL /* dtor */, NULL /* ctx */, @@ -970,7 +970,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/extra", + "/bulkwrite/extra [lock:live-server]", test_bulkwrite_extra, NULL /* dtor */, NULL /* ctx */, @@ -978,7 +978,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/no_verbose_results", + "/bulkwrite/no_verbose_results [lock:live-server]", test_bulkwrite_no_verbose_results, NULL /* dtor */, NULL /* ctx */, @@ -986,7 +986,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/many_namespaces", + "/bulkwrite/many_namespaces [lock:live-server]", test_bulkwrite_many_namespaces, NULL /* dtor */, NULL /* ctx */, @@ -995,7 +995,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/execute_requires_client", + "/bulkwrite/execute_requires_client [lock:live-server]", test_bulkwrite_execute_requires_client, NULL /* dtor */, NULL /* ctx */, @@ -1003,7 +1003,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/two_large_inserts", + "/bulkwrite/two_large_inserts [lock:live-server]", test_bulkwrite_two_large_inserts, NULL /* dtor */, NULL /* ctx */, @@ -1011,7 +1011,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/client_error_no_result", + "/bulkwrite/client_error_no_result [lock:live-server]", test_bulkwrite_client_error_no_result, NULL /* dtor */, NULL /* ctx */, @@ -1019,7 +1019,7 @@ test_bulkwrite_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/bulkwrite/check_acknowledged", + "/bulkwrite/check_acknowledged [lock:live-server]", test_bulkwrite_check_acknowledged, NULL /* dtor */, NULL /* ctx */, diff --git a/src/libmongoc/tests/test-mongoc-change-stream.c b/src/libmongoc/tests/test-mongoc-change-stream.c index fa14e06cb07..45f4a332104 100644 --- a/src/libmongoc/tests/test-mongoc-change-stream.c +++ b/src/libmongoc/tests/test-mongoc-change-stream.c @@ -2088,7 +2088,7 @@ test_change_stream_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/change_stream/pipeline", test_change_stream_pipeline); TestSuite_AddFull(suite, - "/change_stream/live/track_resume_token", + "/change_stream/live/track_resume_token [lock:live-server]", test_change_stream_live_track_resume_token, NULL, NULL, @@ -2096,21 +2096,21 @@ test_change_stream_install(TestSuite *suite) test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/change_stream/live/batch_size", + "/change_stream/live/batch_size [lock:live-server]", test_change_stream_live_batch_size, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/live/missing_resume_token", + "/change_stream/live/missing_resume_token [lock:live-server]", test_change_stream_live_missing_resume_token, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/live/invalid_resume_token", + "/change_stream/live/invalid_resume_token [lock:live-server]", test_change_stream_live_invalid_resume_token, NULL, NULL, @@ -2121,14 +2121,14 @@ test_change_stream_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/change_stream/options", test_change_stream_options); TestSuite_AddFull(suite, - "/change_stream/live/watch", + "/change_stream/live/watch [lock:live-server]", test_change_stream_live_watch, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/live/read_prefs", + "/change_stream/live/read_prefs [lock:live-server]", test_change_stream_live_read_prefs, NULL, NULL, @@ -2138,28 +2138,28 @@ test_change_stream_install(TestSuite *suite) TestSuite_Add(suite, "/change_stream/server_selection_fails", test_change_stream_server_selection_fails); TestSuite_AddFull(suite, - "/change_stream/next_after_error", + "/change_stream/next_after_error [lock:live-server]", test_change_stream_next_after_error, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/accepts_array", + "/change_stream/accepts_array [lock:live-server]", test_change_stream_accepts_array, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddMockServerTest(suite, "/change_stream/getmore_errors", test_getmore_errors); TestSuite_AddFull(suite, - "/change_stream/start_at_operation_time", + "/change_stream/start_at_operation_time [lock:live-server]", test_change_stream_start_at_operation_time, NULL, NULL, test_framework_skip_if_not_replset, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/change_stream/resume_with_post_batch_resume_token", + "/change_stream/resume_with_post_batch_resume_token [lock:live-server]", test_change_stream_resume_with_post_batch_resume_token, NULL, NULL, @@ -2167,26 +2167,42 @@ test_change_stream_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/change_stream/database", + "/change_stream/database [lock:live-server]", test_change_stream_database_watch, NULL, NULL, test_framework_skip_if_not_replset); - TestSuite_AddFull( - suite, "/change_stream/client", test_change_stream_client_watch, NULL, NULL, test_framework_skip_if_not_replset); - TestSuite_AddMockServerTest(suite, "/change_stream/resume_with_first_doc", test_resume_cases); + TestSuite_AddFull(suite, + "/change_stream/client [lock:live-server]", + test_change_stream_client_watch, + NULL, + NULL, + test_framework_skip_if_not_replset); + TestSuite_AddMockServerTest(suite, "/change_stream/resume_with_first_doc [timeout:10]", test_resume_cases); TestSuite_AddMockServerTest(suite, - "/change_stream/resume_with_first_doc/post_batch_resume_token", + "/change_stream/resume_with_first_doc/post_batch_resume_token [timeout:10]", test_resume_cases_with_post_batch_resume_token); - TestSuite_AddFull( - suite, "/change_stream/error_null_doc", test_error_null_doc, NULL, NULL, test_framework_skip_if_not_replset); - TestSuite_AddFull( - suite, "/change_stream/live/prose_test_11", prose_test_11, NULL, NULL, test_framework_skip_if_not_replset); + TestSuite_AddFull(suite, + "/change_stream/error_null_doc [lock:live-server]", + test_error_null_doc, + NULL, + NULL, + test_framework_skip_if_not_replset); + TestSuite_AddFull(suite, + "/change_stream/live/prose_test_11 [lock:live-server]", + prose_test_11, + NULL, + NULL, + test_framework_skip_if_not_replset); // Prose test 12 is removed. C driver does not support server 4.0.7. - TestSuite_AddFull( - suite, "/change_stream/live/prose_test_13", prose_test_13, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/live/prose_test_14", + "/change_stream/live/prose_test_13 [lock:live-server]", + prose_test_13, + NULL, + NULL, + test_framework_skip_if_not_replset); + TestSuite_AddFull(suite, + "/change_stream/live/prose_test_14 [lock:live-server]", prose_test_14, NULL, NULL, @@ -2195,13 +2211,13 @@ test_change_stream_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/change_streams/prose_test_17", prose_test_17); TestSuite_AddMockServerTest(suite, "/change_streams/prose_test_18", prose_test_18); TestSuite_AddFull(suite, - "/change_streams/iterate_after_invalidate", + "/change_streams/iterate_after_invalidate [lock:live-server]", iterate_after_invalidate, NULL, NULL, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/change_stream/batchSize0", + "/change_stream/batchSize0 [lock:live-server]", test_change_stream_batchSize0, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-client-pool.c b/src/libmongoc/tests/test-mongoc-client-pool.c index 3878b215117..76274925561 100644 --- a/src/libmongoc/tests/test-mongoc-client-pool.c +++ b/src/libmongoc/tests/test-mongoc-client-pool.c @@ -613,7 +613,7 @@ test_client_pool_install(TestSuite *suite) TestSuite_Add(suite, "/ClientPool/handshake", test_mongoc_client_pool_handshake); TestSuite_AddFull(suite, - "/ClientPool/create_client_pool_unused_session", + "/ClientPool/create_client_pool_unused_session [lock:live-server]", test_client_pool_create_unused_session, NULL /* dtor */, NULL /* ctx */, @@ -623,11 +623,13 @@ test_client_pool_install(TestSuite *suite) #endif TestSuite_AddLive(suite, "/ClientPool/destroy_without_push", test_client_pool_destroy_without_pushing); TestSuite_AddLive(suite, "/ClientPool/max_pool_size_exceeded", test_client_pool_max_pool_size_exceeded); - TestSuite_Add(suite, "/ClientPool/can_override_sockettimeoutms", test_client_pool_can_override_sockettimeoutms); + TestSuite_Add(suite, + "/ClientPool/can_override_sockettimeoutms [lock:live-server]", + test_client_pool_can_override_sockettimeoutms); TestSuite_AddFull( suite, - "/client_pool/disconnects_removed_servers/on_push", + "/client_pool/disconnects_removed_servers/on_push [lock:live-server]", disconnects_removed_servers_on_push, NULL, NULL, @@ -636,7 +638,7 @@ test_client_pool_install(TestSuite *suite) TestSuite_AddFull( suite, - "/client_pool/disconnects_removed_servers/in_pool", + "/client_pool/disconnects_removed_servers/in_pool [lock:live-server]", disconnects_removed_servers_in_pool, NULL, NULL, @@ -644,7 +646,8 @@ test_client_pool_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_9 /* require server 4.4+ for streaming monitoring protocol */); #if defined(MONGOC_ENABLE_SSL_OPENSSL) - TestSuite_Add(suite, "/ClientPool/openssl/change_ssl_opts", test_mongoc_client_pool_change_openssl_ctx); + TestSuite_Add( + suite, "/ClientPool/openssl/change_ssl_opts [lock:live-server]", test_mongoc_client_pool_change_openssl_ctx); #endif #if defined(MONGOC_ENABLE_SSL) diff --git a/src/libmongoc/tests/test-mongoc-client-session.c b/src/libmongoc/tests/test-mongoc-client-session.c index f65fc3a230b..33efebeaba6 100644 --- a/src/libmongoc/tests/test-mongoc-client-session.c +++ b/src/libmongoc/tests/test-mongoc-client-session.c @@ -2394,7 +2394,7 @@ test_unacknowledged_explicit_cs_explicit_wc(void *ctx) session_test_helper_t *const helper = bson_malloc(sizeof(*helper)); \ *helper = (session_test_helper_t){.test_fn = (_test_fn)}; \ TestSuite_AddFull(_suite, \ - _name, \ + _name " [lock:live-server]", \ (_allow_read_concern) ? run_session_test : run_session_test_no_rc, \ &bson_free, \ helper, \ @@ -2408,7 +2408,7 @@ test_unacknowledged_explicit_cs_explicit_wc(void *ctx) session_test_helper_t *const helper = bson_malloc(sizeof(*helper)); \ *helper = (session_test_helper_t){.test_fn = (_test_fn)}; \ TestSuite_AddFull(_suite, \ - _name, \ + _name " [lock:live-server]", \ (_allow_read_concern) ? run_session_test : run_session_test_no_rc, \ &bson_free, \ helper, \ @@ -2423,7 +2423,7 @@ test_unacknowledged_explicit_cs_explicit_wc(void *ctx) session_test_helper_t *const helper = bson_malloc(sizeof(*helper)); \ *helper = (session_test_helper_t){.test_fn = (_test_fn)}; \ TestSuite_AddFull(_suite, \ - _name, \ + _name " [lock:live-server]", \ (_explicit_cs) ? (_inherit_wc ? test_unacknowledged_explicit_cs_inherit_wc \ : test_unacknowledged_implicit_cs_explicit_wc) \ : (_inherit_wc ? test_unacknowledged_implicit_cs_inherit_wc \ @@ -2598,7 +2598,7 @@ test_session_install(TestSuite *suite) TestSuite_Add( suite, "/Session/opts/causal_consistency_and_snapshot", test_session_opts_causal_consistency_and_snapshot); TestSuite_AddFull(suite, - "/Session/no_crypto", + "/Session/no_crypto [lock:live-server]", test_session_no_crypto, NULL, NULL, @@ -2606,21 +2606,21 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_sessions, test_framework_skip_if_crypto); TestSuite_AddFull(suite, - "/Session/lifo/single", + "/Session/lifo/single [lock:live-server]", test_session_pool_lifo_single, NULL, NULL, test_framework_skip_if_no_sessions, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/lifo/pooled", + "/Session/lifo/pooled [lock:live-server]", test_session_pool_lifo_pooled, NULL, NULL, test_framework_skip_if_no_sessions, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/timeout/single", + "/Session/timeout/single [lock:live-server][timeout:30]", test_session_pool_timeout_single, NULL, NULL, @@ -2628,7 +2628,7 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/timeout/pooled", + "/Session/timeout/pooled [lock:live-server][timeout:30]", test_session_pool_timeout_pooled, NULL, NULL, @@ -2636,7 +2636,7 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/reap/single", + "/Session/reap/single [lock:live-server][timeout:30]", test_session_pool_reap_single, NULL, NULL, @@ -2644,7 +2644,7 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/reap/pooled", + "/Session/reap/pooled [lock:live-server][timeout:30]", test_session_pool_reap_pooled, NULL, NULL, @@ -2652,21 +2652,21 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/id_bad", + "/Session/id_bad [lock:live-server]", test_session_id_bad, NULL, NULL, test_framework_skip_if_no_sessions, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/supported/single", + "/Session/supported/single [lock:live-server]", test_session_supported_single, NULL, NULL, TestSuite_CheckLive, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/supported/pooled", + "/Session/supported/pooled [lock:live-server]", test_session_supported_pooled, NULL, NULL, @@ -2677,25 +2677,25 @@ test_session_install(TestSuite *suite) TestSuite_AddMockServerTest( suite, "/Session/end/mock/pooled", test_mock_end_sessions_pooled, test_framework_skip_if_no_crypto); TestSuite_AddMockServerTest(suite, - "/Session/end/mock/disconnected", + "/Session/end/mock/disconnected [timeout:20]", test_mock_end_sessions_server_disconnect, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/end/single", + "/Session/end/single [lock:live-server]", test_end_sessions_single, NULL, NULL, test_framework_skip_if_no_crypto, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/Session/end/pooled", + "/Session/end/pooled [lock:live-server]", test_end_sessions_pooled, NULL, NULL, test_framework_skip_if_no_crypto, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/Session/end/many/single", + "/Session/end/many/single [lock:live-server][timeout:30]", test_end_sessions_many_single, NULL, NULL, @@ -2703,7 +2703,7 @@ test_session_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/end/many/pooled", + "/Session/end/many/pooled [lock:live-server][timeout:30]", test_end_sessions_many_pooled, NULL, NULL, @@ -2711,14 +2711,14 @@ test_session_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Session/advance_cluster_time", + "/Session/advance_cluster_time [lock:live-server]", test_session_advance_cluster_time, NULL, NULL, test_framework_skip_if_no_crypto, test_framework_skip_if_no_sessions); TestSuite_AddFull(suite, - "/Session/advance_operation_time", + "/Session/advance_operation_time [lock:live-server]", test_session_advance_operation_time, NULL, NULL, @@ -2761,7 +2761,7 @@ test_session_install(TestSuite *suite) session_test_helper_t *const helper = bson_malloc(sizeof(*helper)); *helper = (session_test_helper_t){.test_fn = test_bulk_set_session}; TestSuite_AddFull(suite, - "/Session/bulk_set_session", + "/Session/bulk_set_session [lock:live-server]", run_session_test_bulk_operation, &bson_free, helper, @@ -2772,7 +2772,7 @@ test_session_install(TestSuite *suite) session_test_helper_t *const helper = bson_malloc(sizeof(*helper)); *helper = (session_test_helper_t){.test_fn = test_bulk_set_client}; TestSuite_AddFull(suite, - "/Session/bulk_set_client", + "/Session/bulk_set_client [lock:live-server]", run_session_test_bulk_operation, &bson_free, helper, @@ -2780,28 +2780,28 @@ test_session_install(TestSuite *suite) test_framework_skip_if_no_crypto); } TestSuite_AddFull(suite, - "/Session/cursor_implicit_session", + "/Session/cursor_implicit_session [lock:live-server]", test_cursor_implicit_session, NULL, NULL, test_framework_skip_if_no_cluster_time, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/change_stream_implicit_session", + "/Session/change_stream_implicit_session [lock:live-server]", test_change_stream_implicit_session, NULL, NULL, test_framework_skip_if_no_cluster_time, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/cmd_error", + "/Session/cmd_error [lock:live-server]", test_cmd_error, NULL, NULL, test_framework_skip_if_no_cluster_time, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/Session/read_concern", + "/Session/read_concern [lock:live-server]", test_read_concern, NULL, NULL, @@ -2852,7 +2852,7 @@ test_session_install(TestSuite *suite) suite, JSON_DIR, "sessions/legacy", test_sessions_spec_cb, test_framework_skip_if_no_sessions); TestSuite_AddFull(suite, - "/Session/dirty", + "/Session/dirty [lock:live-server]", test_session_dirty, NULL /* dtor */, NULL /* ctx */, @@ -2862,7 +2862,7 @@ test_session_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/Session/snapshot/prose_test_1", + "/Session/snapshot/prose_test_1 [lock:live-server]", test_sessions_snapshot_prose_test_1, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-client-side-encryption.c b/src/libmongoc/tests/test-mongoc-client-side-encryption.c index 7f22d2bbe80..f36d2294c1e 100644 --- a/src/libmongoc/tests/test-mongoc-client-side-encryption.c +++ b/src/libmongoc/tests/test-mongoc-client-side-encryption.c @@ -19,6 +19,7 @@ #include +#include #include #include @@ -7063,7 +7064,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_no_client_side_encryption); /* Prose tests from the spec. */ TestSuite_AddFull(suite, - "/client_side_encryption/create_datakey_with_custom_key_material", + "/client_side_encryption/create_datakey_with_custom_key_material [lock:live-server]", test_create_datakey_with_custom_key_material, NULL, NULL, @@ -7071,7 +7072,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_offline /* requires AWS */); TestSuite_AddFull(suite, - "/client_side_encryption/datakey_and_double_encryption", + "/client_side_encryption/datakey_and_double_encryption [lock:live-server]", test_datakey_and_double_encryption, NULL, NULL, @@ -7079,7 +7080,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_offline /* requires AWS */); TestSuite_AddFull(suite, - "/client_side_encryption/external_key_vault", + "/client_side_encryption/external_key_vault [lock:live-server]", test_external_key_vault, NULL, NULL, @@ -7087,14 +7088,14 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_no_auth /* requires auth for error check */); TestSuite_AddFull(suite, - "/client_side_encryption/bson_size_limits_and_batch_splitting", + "/client_side_encryption/bson_size_limits_and_batch_splitting [lock:live-server]", test_bson_size_limits_and_batch_splitting_no_qe, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/bson_size_limits_and_batch_splitting_qe", + "/client_side_encryption/bson_size_limits_and_batch_splitting_qe [lock:live-server]", test_bson_size_limits_and_batch_splitting_qe, NULL, NULL, @@ -7102,14 +7103,14 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_25, test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/views_are_prohibited", + "/client_side_encryption/views_are_prohibited [lock:live-server]", test_views_are_prohibited, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/corpus", + "/client_side_encryption/corpus [lock:live-server]", test_corpus, NULL, NULL, @@ -7117,7 +7118,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_offline /* requires AWS */); TestSuite_AddFull(suite, - "/client_side_encryption/custom_endpoint", + "/client_side_encryption/custom_endpoint [lock:live-server]", test_custom_endpoint, NULL, NULL, @@ -7126,7 +7127,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_offline /* requires AWS, Azure, and GCP */); TestSuite_AddFull(suite, "/client_side_encryption/bypass_spawning_mongocryptd/" - "mongocryptdBypassSpawn", + "mongocryptdBypassSpawn [lock:live-server]", test_bypass_spawning_via_mongocryptdBypassSpawn, NULL, NULL, @@ -7134,7 +7135,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, "/client_side_encryption/bypass_spawning_mongocryptd/" - "bypassAutoEncryption", + "bypassAutoEncryption [lock:live-server]", test_bypass_spawning_via_bypassAutoEncryption, NULL, NULL, @@ -7142,7 +7143,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, "/client_side_encryption/bypass_spawning_mongocryptd/" - "bypassQueryAnalysis", + "bypassQueryAnalysis [lock:live-server]", test_bypass_spawning_via_bypassQueryAnalysis, NULL, NULL, @@ -7150,7 +7151,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, "/client_side_encryption/bypass_spawning_mongocryptd/" - "cryptSharedLibLoaded", + "cryptSharedLibLoaded [lock:live-server]", test_bypass_spawning_via_cryptSharedLibLoaded, NULL, NULL, @@ -7158,35 +7159,35 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, _skip_if_no_crypt_shared); TestSuite_AddFull(suite, - "/client_side_encryption/kms_tls/valid", + "/client_side_encryption/kms_tls/valid [lock:live-server]", test_kms_tls_cert_valid, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/kms_tls/expired", + "/client_side_encryption/kms_tls/expired [lock:live-server]", test_kms_tls_cert_expired, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/kms_tls/wrong_host", + "/client_side_encryption/kms_tls/wrong_host [lock:live-server]", test_kms_tls_cert_wrong_host, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/unique_index_on_keyaltnames", + "/client_side_encryption/unique_index_on_keyaltnames [lock:live-server]", test_unique_index_on_keyaltnames, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/prose_test_16/case1", + "/client_side_encryption/prose_test_16/case1 [lock:live-server][timeout:30]", test_rewrap_with_separate_client_encryption, NULL, NULL, @@ -7194,7 +7195,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/client_side_encryption/prose_test_16/case2", + "/client_side_encryption/prose_test_16/case2 [lock:live-server]", test_rewrap_without_provider, NULL, NULL, @@ -7203,28 +7204,28 @@ test_client_side_encryption_install(TestSuite *suite) /* Other, C driver specific, tests. */ TestSuite_AddFull(suite, - "/client_side_encryption/single_and_pool_mismatches", + "/client_side_encryption/single_and_pool_mismatches [lock:live-server]", test_invalid_single_and_pool_mismatches, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/multi_threaded", + "/client_side_encryption/multi_threaded [lock:live-server]", test_multi_threaded, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/malformed_explicit", + "/client_side_encryption/malformed_explicit [lock:live-server]", test_malformed_explicit, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/kms_tls_options", + "/client_side_encryption/kms_tls_options [lock:live-server]", test_kms_tls_options, NULL, NULL, @@ -7236,20 +7237,20 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_windows); TestSuite_AddFull(suite, - "/client_side_encryption/kms_tls_options/extra_rejected", + "/client_side_encryption/kms_tls_options/extra_rejected [lock:live-server]", test_kms_tls_options_extra_rejected, NULL, NULL, test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, - "/client_side_encryption/kms_retry", + "/client_side_encryption/kms_retry [lock:live-server]", test_kms_retry, NULL, NULL, test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, - "/client_side_encryption/explicit_encryption/case1", + "/client_side_encryption/explicit_encryption/case1 [lock:live-server]", test_explicit_encryption_case1, NULL /* dtor */, NULL /* ctx */, @@ -7258,7 +7259,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/explicit_encryption/case2", + "/client_side_encryption/explicit_encryption/case2 [lock:live-server]", test_explicit_encryption_case2, NULL /* dtor */, NULL /* ctx */, @@ -7267,7 +7268,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/explicit_encryption/case3", + "/client_side_encryption/explicit_encryption/case3 [lock:live-server]", test_explicit_encryption_case3, NULL /* dtor */, NULL /* ctx */, @@ -7276,7 +7277,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/explicit_encryption/case4", + "/client_side_encryption/explicit_encryption/case4 [lock:live-server]", test_explicit_encryption_case4, NULL /* dtor */, NULL /* ctx */, @@ -7285,7 +7286,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/explicit_encryption/case5", + "/client_side_encryption/explicit_encryption/case5 [lock:live-server]", test_explicit_encryption_case5, NULL /* dtor */, NULL /* ctx */, @@ -7294,7 +7295,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/decryption_events/case1", + "/client_side_encryption/decryption_events/case1 [lock:live-server]", test_decryption_events_case1, NULL /* dtor */, NULL /* ctx */, @@ -7302,7 +7303,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/decryption_events/case2", + "/client_side_encryption/decryption_events/case2 [lock:live-server]", test_decryption_events_case2, NULL /* dtor */, NULL /* ctx */, @@ -7310,7 +7311,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/decryption_events/case3", + "/client_side_encryption/decryption_events/case3 [lock:live-server]", test_decryption_events_case3, NULL /* dtor */, NULL /* ctx */, @@ -7319,7 +7320,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_AddFull(suite, - "/client_side_encryption/decryption_events/case4", + "/client_side_encryption/decryption_events/case4 [lock:live-server]", test_decryption_events_case4, NULL /* dtor */, NULL /* ctx */, @@ -7327,7 +7328,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/qe_docs_example", + "/client_side_encryption/qe_docs_example [lock:live-server]", test_qe_docs_example, NULL /* dtor */, NULL /* ctx */, @@ -7336,7 +7337,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/kms/callback", + "/client_side_encryption/kms/callback [lock:live-server]", test_kms_callback, NULL, // dtor NULL, // ctx @@ -7344,7 +7345,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddFull(suite, - "/client_side_encryption/kms/auto-aws/fail", + "/client_side_encryption/kms/auto-aws/fail [lock:live-server]", test_auto_aws_fail, NULL, NULL, @@ -7353,7 +7354,7 @@ test_client_side_encryption_install(TestSuite *suite) _not_have_aws_creds_env); TestSuite_AddFull(suite, - "/client_side_encryption/kms/auto-aws/succeed", + "/client_side_encryption/kms/auto-aws/succeed [lock:live-server]", test_auto_aws_succeed, NULL, NULL, @@ -7362,17 +7363,18 @@ test_client_side_encryption_install(TestSuite *suite) _have_aws_creds_env); TestSuite_AddFull(suite, - "/client_side_encryption/drop_qe_null_error", + "/client_side_encryption/drop_qe_null_error [lock:live-server]", test_drop_qe_null_error, NULL, NULL, test_framework_skip_if_no_client_side_encryption, TestSuite_CheckLive); - TestSuite_AddFull(suite, "/client_side_encryption/auto_datakeys", test_auto_datakeys, NULL, NULL, NULL); + TestSuite_AddFull( + suite, "/client_side_encryption/auto_datakeys [lock:live-server]", test_auto_datakeys, NULL, NULL, NULL); TestSuite_AddFull(suite, - "/client_side_encryption/createEncryptedCollection/simple", + "/client_side_encryption/createEncryptedCollection/simple [lock:live-server]", test_create_encrypted_collection_simple, NULL, NULL, @@ -7382,7 +7384,7 @@ test_client_side_encryption_install(TestSuite *suite) TestSuite_AddFull(suite, "/client_side_encryption/createEncryptedCollection/" - "missing-encryptedFields", + "missing-encryptedFields [lock:live-server]", test_create_encrypted_collection_no_encryptedFields, NULL, NULL, @@ -7391,7 +7393,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single); TestSuite_AddFull(suite, "/client_side_encryption/createEncryptedCollection/" - "bad-keyId", + "bad-keyId [lock:live-server]", test_create_encrypted_collection_bad_keyId, NULL, NULL, @@ -7399,7 +7401,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_21, test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/createEncryptedCollection/insert", + "/client_side_encryption/createEncryptedCollection/insert [lock:live-server]", test_create_encrypted_collection_insert, NULL, NULL, @@ -7407,7 +7409,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_21, test_framework_skip_if_single); TestSuite_AddFull(suite, - "/client_side_encryption/bypass_mongocryptd_shared_library", + "/client_side_encryption/bypass_mongocryptd_shared_library [lock:live-server]", test_bypass_mongocryptd_shared_library, NULL, NULL, @@ -7450,12 +7452,14 @@ test_client_side_encryption_install(TestSuite *suite) char *test_name = bson_strdup_printf("/client_side_encryption/range_explicit_encryption/%s/%s", rc.name, rangeType); + mstr name_with_tags = mstr_copy_cstring(test_name); + mstr_append(&name_with_tags, mstr_cstring(" [lock:live-server]")); // Skip DecimalNoPrecision if not a replica set. if (0 == strcmp(rangeType, "DecimalNoPrecision")) { TestSuite_AddFull( suite, - test_name, + name_with_tags.data, rc.fn, NULL /* dtor */, (void *)rangeTypes[i] /* ctx */, @@ -7465,7 +7469,7 @@ test_client_side_encryption_install(TestSuite *suite) } else { TestSuite_AddFull( suite, - test_name, + name_with_tags.data, rc.fn, NULL /* dtor */, (void *)rangeTypes[i] /* ctx */, @@ -7473,13 +7477,14 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_25, /* range queries require MongoDB 8.0+ */ test_framework_skip_if_single); } + mstr_destroy(&name_with_tags); bson_free(test_name); } } TestSuite_AddFull(suite, - "/client_side_encryption/range_explicit_encryption/applies_defaults", + "/client_side_encryption/range_explicit_encryption/applies_defaults [lock:live-server]", test_range_explicit_encryption_applies_defaults, NULL, NULL, @@ -7487,7 +7492,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, - "/client_side_encryption/test_lookup", + "/client_side_encryption/test_lookup [lock:live-server]", test_lookup, NULL, NULL, @@ -7495,7 +7500,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single, /* QE not supported on standalone */ test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, - "/client_side_encryption/test_lookup/post-8.2", + "/client_side_encryption/test_lookup/post-8.2 [lock:live-server]", test_lookup_post82, NULL, NULL, @@ -7504,7 +7509,7 @@ test_client_side_encryption_install(TestSuite *suite) test_framework_skip_if_single, /* QE not supported on standalone */ test_framework_skip_if_no_client_side_encryption); TestSuite_AddFull(suite, - "/client_side_encryption/test_lookup/pre-8.1", + "/client_side_encryption/test_lookup/pre-8.1 [lock:live-server]", test_lookup_pre81, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-client.c b/src/libmongoc/tests/test-mongoc-client.c index 9df2a07db47..04ba91a023e 100644 --- a/src/libmongoc/tests/test-mongoc-client.c +++ b/src/libmongoc/tests/test-mongoc-client.c @@ -3839,33 +3839,37 @@ test_killCursors(void) void test_client_install(TestSuite *suite) { - TestSuite_AddLive(suite, "/Client/ipv6/single", test_mongoc_client_ipv6_single); - TestSuite_AddLive(suite, "/Client/ipv6/pooled", test_mongoc_client_ipv6_pooled); + TestSuite_AddLive(suite, "/Client/ipv6/single [ipv6]", test_mongoc_client_ipv6_single); + TestSuite_AddLive(suite, "/Client/ipv6/pooled [ipv6]", test_mongoc_client_ipv6_pooled); - TestSuite_AddFull( - suite, "/Client/authenticate", test_mongoc_client_authenticate, NULL, NULL, test_framework_skip_if_no_auth); TestSuite_AddFull(suite, - "/Client/speculative_auth_failure/single", + "/Client/authenticate [lock:live-server]", + test_mongoc_client_authenticate, + NULL, + NULL, + test_framework_skip_if_no_auth); + TestSuite_AddFull(suite, + "/Client/speculative_auth_failure/single [lock:live-server]", test_mongoc_client_single_speculative_auth_failure, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/Client/speculative_auth_failure/pooled", + "/Client/speculative_auth_failure/pooled [lock:live-server]", test_mongoc_client_pooled_speculative_auth_failure, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/Client/authenticate_cached/pool", + "/Client/authenticate_cached/pool [lock:live-server]", test_mongoc_client_authenticate_cached_pooled, NULL, NULL, test_framework_skip_if_no_auth); TestSuite_AddFull(suite, - "/Client/authenticate_cached/client", + "/Client/authenticate_cached/client [lock:live-server]", test_mongoc_client_authenticate_cached_single, NULL, NULL, @@ -3875,23 +3879,31 @@ test_client_install(TestSuite *suite) // was introduced in server 4.4 (maxWireVersion=9) test_framework_skip_if_max_wire_version_more_than_8); TestSuite_AddFull(suite, - "/Client/authenticate_failure", + "/Client/authenticate_failure [lock:live-server]", test_mongoc_client_authenticate_failure, NULL, NULL, test_framework_skip_if_no_auth); TestSuite_AddFull(suite, - "/Client/authenticate_timeout", + "/Client/authenticate_timeout [lock:live-server]", test_mongoc_client_authenticate_timeout, NULL, NULL, test_framework_skip_if_no_auth); TestSuite_AddMockServerTest(suite, "/Client/command_w_server_id", test_client_cmd_w_server_id); TestSuite_AddMockServerTest(suite, "/Client/command_w_server_id/sharded", test_client_cmd_w_server_id_sharded); - TestSuite_AddFull( - suite, "/Client/command_w_server_id/option", test_server_id_option, NULL, NULL, test_framework_skip_if_auth); - TestSuite_AddFull( - suite, "/Client/command_w_write_concern", test_client_cmd_w_write_concern, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Client/command_w_server_id/option [lock:live-server]", + test_server_id_option, + NULL, + NULL, + test_framework_skip_if_auth); + TestSuite_AddFull(suite, + "/Client/command_w_write_concern [lock:live-server]", + test_client_cmd_w_write_concern, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddMockServerTest(suite, "/Client/command/write_concern", test_client_cmd_write_concern); TestSuite_AddMockServerTest(suite, "/Client/command/write_concern_fam", test_client_cmd_write_concern_fam); TestSuite_AddMockServerTest( @@ -3921,14 +3933,18 @@ test_client_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/Client/mongos_seeds_reconnect/pooled", test_mongos_seeds_reconnect_pooled); TestSuite_AddFull(suite, "/Client/recovering", test_recovering, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, "/Client/database_names", test_get_database_names); - TestSuite_AddFull( - suite, "/Client/connect/uds", test_mongoc_client_unix_domain_socket, NULL, NULL, test_framework_skip_if_no_uds); + TestSuite_AddFull(suite, + "/Client/connect/uds [lock:live-server]", + test_mongoc_client_unix_domain_socket, + NULL, + NULL, + test_framework_skip_if_no_uds); TestSuite_AddMockServerTest(suite, "/Client/mismatched_me", test_mongoc_client_mismatched_me); TestSuite_AddMockServerTest(suite, "/Client/handshake/pool", test_mongoc_handshake_pool); TestSuite_Add(suite, "/Client/application_handshake", test_mongoc_client_application_handshake); TestSuite_AddFull(suite, - "/Client/sends_handshake_single", + "/Client/sends_handshake_single [lock:live-server][timeout:30]", test_client_sends_handshake_single, NULL, NULL, @@ -3968,8 +3984,12 @@ test_client_install(TestSuite *suite) TestSuite_AddLive(suite, "/Client/get_description/single", test_mongoc_client_get_description_single); TestSuite_AddLive(suite, "/Client/get_description/pooled", test_mongoc_client_get_description_pooled); TestSuite_AddLive(suite, "/Client/descriptions/single", test_mongoc_client_descriptions_single); - TestSuite_AddFull( - suite, "/Client/descriptions/pooled", test_mongoc_client_descriptions_pooled, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Client/descriptions/pooled [lock:live-server]", + test_mongoc_client_descriptions_pooled, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddLive(suite, "/Client/select_server/single", test_mongoc_client_select_server_single); TestSuite_AddLive(suite, "/Client/select_server/pooled", test_mongoc_client_select_server_pooled); TestSuite_AddLive(suite, "/Client/select_server/err/single", test_mongoc_client_select_server_error_single); @@ -3981,13 +4001,13 @@ test_client_install(TestSuite *suite) suite, "/Client/fetch_stream/retry/succeed", test_mongoc_client_fetch_stream_retry_succeed); TestSuite_AddMockServerTest(suite, "/Client/fetch_stream/retry/fail", test_mongoc_client_fetch_stream_retry_fail); TestSuite_AddFull(suite, - "/Client/null_error_pointer/single", + "/Client/null_error_pointer/single [timeout:30]", test_null_error_pointer_single, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Client/null_error_pointer/pooled", + "/Client/null_error_pointer/pooled [timeout:30]", test_null_error_pointer_pooled, NULL, NULL, @@ -3995,10 +4015,12 @@ test_client_install(TestSuite *suite) TestSuite_Add(suite, "/Client/get_database", test_get_database); TestSuite_Add(suite, "/Client/invalid_server_id", test_invalid_server_id); TestSuite_AddMockServerTest(suite, "/Client/recv_network_error", test_mongoc_client_recv_network_error); - TestSuite_AddLive( - suite, "/Client/get_handshake_hello_response/single", test_mongoc_client_get_handshake_hello_response_single); - TestSuite_AddLive( - suite, "/Client/get_handshake_hello_response/pooled", test_mongoc_client_get_handshake_hello_response_pooled); + TestSuite_AddLive(suite, + "/Client/get_handshake_hello_response/single [timeout:30]", + test_mongoc_client_get_handshake_hello_response_single); + TestSuite_AddLive(suite, + "/Client/get_handshake_hello_response/pooled [timeout:30]", + test_mongoc_client_get_handshake_hello_response_pooled); TestSuite_AddLive(suite, "/Client/get_handshake_establishes_connection/single", test_mongoc_client_get_handshake_establishes_connection_single); @@ -4008,17 +4030,21 @@ test_client_install(TestSuite *suite) TestSuite_AddMockServerTest( suite, "/Client/resends_handshake_on_network_error", test_mongoc_client_resends_handshake_on_network_error); TestSuite_Add(suite, "/Client/failure_to_auth", test_failure_to_auth); - TestSuite_AddFull( - suite, "/Client/failure_to_auth_logs", test_failure_to_auth_logs, NULL, NULL, test_framework_skip_if_no_auth); + TestSuite_AddFull(suite, + "/Client/failure_to_auth_logs [lock:live-server]", + test_failure_to_auth_logs, + NULL, + NULL, + test_framework_skip_if_no_auth); #if defined(MONGOC_ENABLE_SSL_OPENSSL) TestSuite_AddFull(suite, - "/Client/openssl/change_ssl_opts_before_ops", + "/Client/openssl/change_ssl_opts_before_ops [lock:live-server]", test_mongoc_client_change_openssl_ctx_before_ops, NULL, NULL, test_framework_skip_if_no_server_ssl); TestSuite_AddFull(suite, - "/Client/openssl/change_ssl_opts_after_ops", + "/Client/openssl/change_ssl_opts_after_ops [lock:live-server]", test_mongoc_client_change_openssl_ctx_between_ops, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-cluster.c b/src/libmongoc/tests/test-mongoc-cluster.c index 8ff862b0e90..ab7e54361fa 100644 --- a/src/libmongoc/tests/test-mongoc-cluster.c +++ b/src/libmongoc/tests/test-mongoc-cluster.c @@ -1547,13 +1547,13 @@ test_cluster_install(TestSuite *suite) TestSuite_AddLive(suite, "/Cluster/test_get_max_bson_obj_size", test_get_max_bson_obj_size); TestSuite_AddLive(suite, "/Cluster/test_get_max_msg_size", test_get_max_msg_size); TestSuite_AddFull(suite, - "/Cluster/disconnect/single", + "/Cluster/disconnect/single [timeout:30]", test_cluster_node_disconnect_single, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Cluster/disconnect/pooled", + "/Cluster/disconnect/pooled [timeout:30]", test_cluster_node_disconnect_pooled, NULL, NULL, @@ -1561,30 +1561,31 @@ test_cluster_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/Cluster/command/timeout/single", test_cluster_command_timeout_single); TestSuite_AddMockServerTest(suite, "/Cluster/command/timeout/pooled", test_cluster_command_timeout_pooled); TestSuite_AddFull(suite, - "/Cluster/write_command/disconnect", + "/Cluster/write_command/disconnect [timeout:30]", test_write_command_disconnect, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddLive(suite, "/Cluster/cluster_time/command_simple/single", test_cluster_time_command_simple_single); - TestSuite_AddLive(suite, "/Cluster/cluster_time/command_simple/pooled", test_cluster_time_command_simple_pooled); + TestSuite_AddLive( + suite, "/Cluster/cluster_time/command_simple/pooled [timeout:30]", test_cluster_time_command_simple_pooled); TestSuite_AddLive( suite, "/Cluster/cluster_time/command_with_opts/single", test_cluster_time_command_with_opts_single); TestSuite_AddLive( - suite, "/Cluster/cluster_time/command_with_opts/pooled", test_cluster_time_command_with_opts_pooled); + suite, "/Cluster/cluster_time/command_with_opts/pooled [timeout:30]", test_cluster_time_command_with_opts_pooled); TestSuite_AddLive(suite, "/Cluster/cluster_time/aggregate/single", test_cluster_time_aggregate_single); - TestSuite_AddLive(suite, "/Cluster/cluster_time/aggregate/pooled", test_cluster_time_aggregate_pooled); + TestSuite_AddLive(suite, "/Cluster/cluster_time/aggregate/pooled [timeout:30]", test_cluster_time_aggregate_pooled); TestSuite_AddLive(suite, "/Cluster/cluster_time/cursor/single", test_cluster_time_cursor_single); - TestSuite_AddLive(suite, "/Cluster/cluster_time/cursor/pooled", test_cluster_time_cursor_pooled); + TestSuite_AddLive(suite, "/Cluster/cluster_time/cursor/pooled [timeout:30]", test_cluster_time_cursor_pooled); TestSuite_AddLive(suite, "/Cluster/cluster_time/insert/single", test_cluster_time_insert_single); - TestSuite_AddLive(suite, "/Cluster/cluster_time/insert/pooled", test_cluster_time_insert_pooled); + TestSuite_AddLive(suite, "/Cluster/cluster_time/insert/pooled [timeout:30]", test_cluster_time_insert_pooled); TestSuite_AddLive(suite, "/Cluster/command/timeout/negative", test_cluster_command_timeout_negative); TestSuite_AddMockServerTest(suite, - "/Cluster/cluster_time/comparison/single", + "/Cluster/cluster_time/comparison/single [timeout:30]", test_cluster_time_comparison_single, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Cluster/cluster_time/comparison/pooled", + "/Cluster/cluster_time/comparison/pooled [timeout:30]", test_cluster_time_comparison_pooled, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, @@ -1592,13 +1593,17 @@ test_cluster_install(TestSuite *suite) test_advanced_cluster_time_not_sent_to_standalone, test_framework_skip_if_no_crypto); TestSuite_AddMockServerTest( - suite, "/Cluster/not_primary/single", test_not_primary_single, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Cluster/not_primary/pooled", test_not_primary_pooled, test_framework_skip_if_slow); + suite, "/Cluster/not_primary/single [timeout:30]", test_not_primary_single, test_framework_skip_if_slow); TestSuite_AddMockServerTest( - suite, "/Cluster/not_primary_auth/single", test_not_primary_auth_single, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Cluster/not_primary_auth/pooled", test_not_primary_auth_pooled, test_framework_skip_if_slow); + suite, "/Cluster/not_primary/pooled [timeout:30]", test_not_primary_pooled, test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Cluster/not_primary_auth/single [timeout:30]", + test_not_primary_auth_single, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Cluster/not_primary_auth/pooled [timeout:30]", + test_not_primary_auth_pooled, + test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, "/Cluster/hello_fails", test_cluster_hello_fails); TestSuite_AddMockServerTest(suite, "/Cluster/hello_hangup", test_cluster_hello_hangup); TestSuite_AddMockServerTest(suite, "/Cluster/command_error/op_msg", test_cluster_command_error); diff --git a/src/libmongoc/tests/test-mongoc-cmd.c b/src/libmongoc/tests/test-mongoc-cmd.c index 441cf5c8d0b..dc6c15a5b7c 100644 --- a/src/libmongoc/tests/test-mongoc-cmd.c +++ b/src/libmongoc/tests/test-mongoc-cmd.c @@ -145,7 +145,7 @@ test_client_cmd_install(TestSuite *suite) { TestSuite_AddMockServerTest(suite, "/Client/cmd/options", test_client_cmd_options); TestSuite_AddFull(suite, - "/cmd/with_two_payload1", + "/cmd/with_two_payload1 [lock:live-server]", test_cmd_with_two_payload1, NULL /* dtor */, NULL /* ctx */, diff --git a/src/libmongoc/tests/test-mongoc-collection.c b/src/libmongoc/tests/test-mongoc-collection.c index fa2828d46a6..8c3ae16f9e6 100644 --- a/src/libmongoc/tests/test-mongoc-collection.c +++ b/src/libmongoc/tests/test-mongoc-collection.c @@ -4959,16 +4959,28 @@ test_collection_install(TestSuite *suite) { test_aggregate_install(suite); - TestSuite_AddFull( - suite, "/Collection/aggregate/write_concern", test_aggregate_w_write_concern, NULL, NULL, TestSuite_CheckLive); - TestSuite_AddFull( - suite, "/Collection/read_prefs_is_valid", test_read_prefs_is_valid, NULL, NULL, test_framework_skip_if_mongos); + TestSuite_AddFull(suite, + "/Collection/aggregate/write_concern [lock:live-server]", + test_aggregate_w_write_concern, + NULL, + NULL, + TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Collection/read_prefs_is_valid [lock:live-server]", + test_read_prefs_is_valid, + NULL, + NULL, + test_framework_skip_if_mongos); TestSuite_AddLive(suite, "/Collection/insert_many", test_insert_many); TestSuite_AddLive(suite, "/Collection/copy", test_copy); TestSuite_AddLive(suite, "/Collection/insert", test_insert); TestSuite_AddLive(suite, "/Collection/insert/null_string", test_insert_null); - TestSuite_AddFull( - suite, "/Collection/insert/oversize", test_insert_oversize, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/Collection/insert/oversize [lock:live-server][timeout:30]", + test_insert_oversize, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddMockServerTest(suite, "/Collection/insert/keys", test_insert_command_keys); TestSuite_AddLive(suite, "/Collection/insert/w0", test_insert_w0); TestSuite_AddLive(suite, "/Collection/update/w0", test_update_w0); @@ -4978,31 +4990,53 @@ test_collection_install(TestSuite *suite) TestSuite_AddLive(suite, "/Collection/index_w_write_concern", test_index_w_write_concern); TestSuite_AddMockServerTest(suite, "/Collection/index/collation", test_index_with_collation); TestSuite_AddLive(suite, "/Collection/index_compound", test_index_compound); - TestSuite_AddFull( - suite, "/Collection/index_geo", test_index_geo, NULL, NULL, test_framework_skip_if_max_wire_version_more_than_9); + TestSuite_AddFull(suite, + "/Collection/index_geo [lock:live-server]", + test_index_geo, + NULL, + NULL, + test_framework_skip_if_max_wire_version_more_than_9); TestSuite_AddLive(suite, "/Collection/index_storage", test_index_storage); TestSuite_AddLive(suite, "/Collection/regex", test_regex); - TestSuite_AddFull(suite, "/Collection/decimal128", test_decimal128, NULL, NULL, skip_unless_server_has_decimal128); + TestSuite_AddFull(suite, + "/Collection/decimal128 [lock:live-server]", + test_decimal128, + NULL, + NULL, + skip_unless_server_has_decimal128); TestSuite_AddLive(suite, "/Collection/update", test_update); - TestSuite_AddFull(suite, "/Collection/update_pipeline", test_update_pipeline, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull( + suite, "/Collection/update_pipeline [lock:live-server]", test_update_pipeline, NULL, NULL, TestSuite_CheckLive); TestSuite_AddLive(suite, "/Collection/update/multi", test_update_multi); TestSuite_AddLive(suite, "/Collection/update/upsert", test_update_upsert); - TestSuite_AddFull( - suite, "/Collection/update/oversize", test_update_oversize, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/Collection/update/oversize [lock:live-server][timeout:30]", + test_update_oversize, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/Collection/remove", test_remove); TestSuite_AddLive(suite, "/Collection/remove/multi", test_remove_multi); - TestSuite_AddFull( - suite, "/Collection/remove/oversize", test_remove_oversize, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/Collection/remove/oversize [lock:live-server][timeout:30]", + test_remove_oversize, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/Collection/drop", test_drop); TestSuite_AddLive(suite, "/Collection/aggregate", test_aggregate); TestSuite_AddMockServerTest(suite, "/Collection/aggregate/inherit/collection", test_aggregate_inherit_collection); TestSuite_AddLive(suite, "/Collection/aggregate/large", test_aggregate_large); - TestSuite_AddFull( - suite, "/Collection/aggregate/secondary", test_aggregate_secondary, NULL, NULL, test_framework_skip_if_mongos); + TestSuite_AddFull(suite, + "/Collection/aggregate/secondary [lock:live-server]", + test_aggregate_secondary, + NULL, + NULL, + test_framework_skip_if_mongos); TestSuite_AddMockServerTest(suite, "/Collection/aggregate/secondary/sharded", test_aggregate_secondary_sharded); TestSuite_AddMockServerTest(suite, "/Collection/aggregate/read_concern", test_aggregate_read_concern); TestSuite_AddFull(suite, - "/Collection/aggregate/bypass_document_validation", + "/Collection/aggregate/bypass_document_validation [lock:live-server]", test_aggregate_bypass, NULL, NULL, @@ -5011,19 +5045,27 @@ test_collection_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/Collection/aggregate_w_server_id", test_aggregate_w_server_id); TestSuite_AddMockServerTest(suite, "/Collection/aggregate_w_server_id/sharded", test_aggregate_w_server_id_sharded); TestSuite_AddFull(suite, - "/Collection/aggregate_w_server_id/option", + "/Collection/aggregate_w_server_id/option [lock:live-server]", test_aggregate_server_id_option, NULL, NULL, test_framework_skip_if_auth); TestSuite_AddLive(suite, "/Collection/rename", test_rename); TestSuite_AddMockServerTest(suite, "/Collection/find_read_concern", test_find_read_concern); - TestSuite_AddFull( - suite, "/Collection/getmore_read_concern_live", test_getmore_read_concern_live, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Collection/getmore_read_concern_live [lock:live-server]", + test_getmore_read_concern_live, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddLive(suite, "/Collection/find_and_modify", test_find_and_modify); TestSuite_AddMockServerTest(suite, "/Collection/find_and_modify/write_concern", test_find_and_modify_write_concern); - TestSuite_AddFull( - suite, "/Collection/large_return", test_large_return, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/Collection/large_return [lock:live-server]", + test_large_return, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/Collection/many_return", test_many_return); TestSuite_AddLive(suite, "/Collection/insert_one_validate", test_insert_one_validate); TestSuite_AddLive(suite, "/Collection/insert_many_validate", test_insert_many_validate); @@ -5032,8 +5074,12 @@ test_collection_install(TestSuite *suite) TestSuite_AddLive(suite, "/Collection/get_index_info", test_get_index_info); TestSuite_AddMockServerTest(suite, "/Collection/find_indexes/error", test_find_indexes_err); TestSuite_AddLive(suite, "/Collection/insert/duplicate_key", test_insert_duplicate_key); - TestSuite_AddFull( - suite, "/Collection/create_index/fail", test_create_index_fail, NULL, NULL, test_framework_skip_if_offline); + TestSuite_AddFull(suite, + "/Collection/create_index/fail [lock:live-server]", + test_create_index_fail, + NULL, + NULL, + test_framework_skip_if_offline); TestSuite_AddLive(suite, "/Collection/insert_one", test_insert_one); TestSuite_AddLive(suite, "/Collection/update_and_replace", test_update_and_replace); TestSuite_AddLive(suite, "/Collection/array_filters_validate", test_array_filters_validate); @@ -5051,7 +5097,7 @@ test_collection_install(TestSuite *suite) TestSuite_AddLive(suite, "/Collection/estimated_document_count_live", test_estimated_document_count_live); TestSuite_AddMockServerTest(suite, "/Collection/aggregate_with_batch_size", test_aggregate_with_batch_size); TestSuite_AddFull(suite, - "/Collection/fam/no_error_on_retry", + "/Collection/fam/no_error_on_retry [lock:live-server]", test_fam_no_error_on_retry, NULL, NULL, @@ -5061,7 +5107,7 @@ test_collection_install(TestSuite *suite) TestSuite_AddLive(suite, "/Collection/hint_is_validated/countDocuments", test_hint_is_validated_countDocuments); TestSuite_AddLive(suite, "/Collection/create_indexes_with_opts", test_create_indexes_with_opts); TestSuite_AddFull(suite, - "/Collection/create_indexes_with_opts/commitQuorum/pre44", + "/Collection/create_indexes_with_opts/commitQuorum/pre44 [lock:live-server]", test_create_indexes_with_opts_commitQuorum_pre44, NULL /* _dtor */, NULL /* _ctx */, @@ -5070,7 +5116,7 @@ test_collection_install(TestSuite *suite) // Server Version 4.4 has Wire Version 9. test_framework_skip_if_max_wire_version_more_than_8); TestSuite_AddFull(suite, - "/Collection/create_indexes_with_opts/commitQuorum/post44", + "/Collection/create_indexes_with_opts/commitQuorum/post44 [lock:live-server]", test_create_indexes_with_opts_commitQuorum_post44, NULL /* _dtor */, NULL /* _ctx */, @@ -5079,7 +5125,7 @@ test_collection_install(TestSuite *suite) // Server Version 4.4 has Wire Version 9. test_framework_skip_if_max_wire_version_less_than_9); TestSuite_AddFull(suite, - "/Collection/create_indexes_with_opts/no_retry", + "/Collection/create_indexes_with_opts/no_retry [lock:live-server]", test_create_indexes_with_opts_no_retry, NULL /* _dtor */, NULL /* _ctx */, @@ -5088,7 +5134,7 @@ test_collection_install(TestSuite *suite) TestSuite_AddLive(suite, "/Collection/insert_one_reports_id", test_insert_one_reports_id); TestSuite_AddFull(suite, - "/Collection/test_create_indexes_acts_as_write_command", + "/Collection/test_create_indexes_acts_as_write_command [lock:live-server]", test_create_indexes_acts_as_write_command, NULL /* _dtor */, NULL /* _ctx */, diff --git a/src/libmongoc/tests/test-mongoc-counters.c b/src/libmongoc/tests/test-mongoc-counters.c index ee68861ad69..5ff35d15132 100644 --- a/src/libmongoc/tests/test-mongoc-counters.c +++ b/src/libmongoc/tests/test-mongoc-counters.c @@ -1455,14 +1455,14 @@ test_counters_install(TestSuite *suite) BSON_UNUSED(suite); #ifdef MONGOC_ENABLE_SHM_COUNTERS TestSuite_AddFull(suite, - "/counters/op_msg", + "/counters/op_msg [lock:live-server]", test_counters_op_msg, NULL, NULL, test_framework_skip_if_compressors, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/counters/op_compressed", + "/counters/op_compressed [lock:live-server]", test_counters_op_compressed, NULL, NULL, @@ -1470,9 +1470,10 @@ test_counters_install(TestSuite *suite) TestSuite_CheckLive); TestSuite_AddLive(suite, "/counters/cursors", test_counters_cursors); TestSuite_AddLive(suite, "/counters/clients", test_counters_clients); - TestSuite_AddFull(suite, "/counters/streams", test_counters_streams, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull( + suite, "/counters/streams [lock:live-server]", test_counters_streams, NULL, NULL, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/counters/auth", + "/counters/auth [lock:live-server]", test_counters_auth, NULL, NULL, @@ -1510,14 +1511,14 @@ test_counters_install(TestSuite *suite) #if defined(MONGOC_ENABLE_SSL) TestSuite_AddFull(suite, - "/counters/rpc/op_egress/auth/single/op_query", + "/counters/rpc/op_egress/auth/single/op_query [lock:live-server]", test_counters_auth_single_op_query, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/counters/rpc/op_egress/auth/single/op_msg", + "/counters/rpc/op_egress/auth/single/op_msg [lock:live-server]", test_counters_auth_single_op_msg, NULL, NULL, @@ -1525,14 +1526,14 @@ test_counters_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_13, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/counters/rpc/op_egress/auth/pooled/op_query", + "/counters/rpc/op_egress/auth/pooled/op_query [lock:live-server]", test_counters_auth_pooled_op_query, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/counters/rpc/op_egress/auth/pooled/op_msg", + "/counters/rpc/op_egress/auth/pooled/op_msg [lock:live-server]", test_counters_auth_pooled_op_msg, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-crud.c b/src/libmongoc/tests/test-mongoc-crud.c index 0671a4930e4..f244ecfa1a5 100644 --- a/src/libmongoc/tests/test-mongoc-crud.c +++ b/src/libmongoc/tests/test-mongoc-crud.c @@ -1377,42 +1377,42 @@ test_crud_install(TestSuite *suite) test_all_spec_tests(suite); TestSuite_AddFull(suite, - "/crud/prose_test_1", + "/crud/prose_test_1 [lock:live-server]", prose_test_1, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/crud/prose_test_2", + "/crud/prose_test_2 [lock:live-server]", prose_test_2, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_max_wire_version_less_than_13); TestSuite_AddFull(suite, - "/crud/prose_test_3", + "/crud/prose_test_3 [lock:live-server]", prose_test_3, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_max_wire_version_less_than_25 /* require 8.0+ server */); TestSuite_AddFull(suite, - "/crud/prose_test_4", + "/crud/prose_test_4 [lock:live-server]", prose_test_4, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_max_wire_version_less_than_25 /* require 8.0+ server */); TestSuite_AddFull(suite, - "/crud/prose_test_5", + "/crud/prose_test_5 [lock:live-server]", prose_test_5, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_max_wire_version_less_than_25 /* require 8.0+ server */); TestSuite_AddFull(suite, - "/crud/prose_test_6", + "/crud/prose_test_6 [lock:live-server][timeout:30]", prose_test_6, NULL, /* dtor */ NULL, /* ctx */ @@ -1421,7 +1421,7 @@ test_crud_install(TestSuite *suite) TestSuite_AddFull(suite, - "/crud/prose_test_7", + "/crud/prose_test_7 [lock:live-server]", prose_test_7, NULL, /* dtor */ NULL, /* ctx */ @@ -1430,7 +1430,7 @@ test_crud_install(TestSuite *suite) TestSuite_AddFull(suite, - "/crud/prose_test_8", + "/crud/prose_test_8 [lock:live-server]", prose_test_8, NULL, /* dtor */ NULL, /* ctx */ @@ -1438,7 +1438,7 @@ test_crud_install(TestSuite *suite) test_framework_skip_if_no_txns); TestSuite_AddFull(suite, - "/crud/prose_test_9", + "/crud/prose_test_9 [lock:live-server]", prose_test_9, NULL, /* dtor */ NULL, /* ctx */ @@ -1446,14 +1446,14 @@ test_crud_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/crud/prose_test_10", + "/crud/prose_test_10 [lock:live-server]", prose_test_10, NULL, /* dtor */ NULL, /* ctx */ test_framework_skip_if_max_wire_version_less_than_25 /* require 8.0+ server */); TestSuite_AddFull(suite, - "/crud/prose_test_11", + "/crud/prose_test_11 [lock:live-server]", prose_test_11, NULL /* dtor */, NULL /* ctx */, @@ -1461,7 +1461,7 @@ test_crud_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/crud/prose_test_12", + "/crud/prose_test_12 [lock:live-server]", prose_test_12, NULL /* dtor */, NULL /* ctx */, @@ -1469,7 +1469,7 @@ test_crud_install(TestSuite *suite) ); TestSuite_AddFull(suite, - "/crud/prose_test_15", + "/crud/prose_test_15 [lock:live-server]", prose_test_15, NULL /* dtor */, NULL /* ctx */, diff --git a/src/libmongoc/tests/test-mongoc-cursor.c b/src/libmongoc/tests/test-mongoc-cursor.c index 076470e4a04..2f80bce1510 100644 --- a/src/libmongoc/tests/test-mongoc-cursor.c +++ b/src/libmongoc/tests/test-mongoc-cursor.c @@ -415,37 +415,37 @@ _make_array_cursor(mongoc_collection_t *coll) return mongoc_client_find_databases_with_opts(coll->client, NULL); } -#define TEST_CURSOR_FIND(prefix, fn) \ - if (1) { \ - make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ - *helper = (make_cursor_helper_t){.ctor = _make_find_cursor}; \ - TestSuite_AddFull(suite, prefix "/find", fn, &bson_free, helper, TestSuite_CheckLive); \ - } else \ +#define TEST_CURSOR_FIND(prefix, fn) \ + if (1) { \ + make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ + *helper = (make_cursor_helper_t){.ctor = _make_find_cursor}; \ + TestSuite_AddFull(suite, prefix "/find [lock:live-server]", fn, &bson_free, helper, TestSuite_CheckLive); \ + } else \ ((void)0) -#define TEST_CURSOR_CMD(prefix, fn) \ - if (1) { \ - make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ - *helper = (make_cursor_helper_t){.ctor = _make_cmd_cursor}; \ - TestSuite_AddFull(suite, prefix "/cmd", fn, &bson_free, helper, TestSuite_CheckLive); \ - } else \ +#define TEST_CURSOR_CMD(prefix, fn) \ + if (1) { \ + make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ + *helper = (make_cursor_helper_t){.ctor = _make_cmd_cursor}; \ + TestSuite_AddFull(suite, prefix "/cmd [lock:live-server]", fn, &bson_free, helper, TestSuite_CheckLive); \ + } else \ ((void)0) -#define TEST_CURSOR_ARRAY(prefix, fn) \ - if (1) { \ - make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ - *helper = (make_cursor_helper_t){.ctor = _make_array_cursor}; \ - TestSuite_AddFull(suite, prefix "/array", fn, &bson_free, helper, TestSuite_CheckLive); \ - } else \ +#define TEST_CURSOR_ARRAY(prefix, fn) \ + if (1) { \ + make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ + *helper = (make_cursor_helper_t){.ctor = _make_array_cursor}; \ + TestSuite_AddFull(suite, prefix "/array [lock:live-server]", fn, &bson_free, helper, TestSuite_CheckLive); \ + } else \ ((void)0) -#define TEST_CURSOR_AGG(prefix, fn) \ - if (1) { \ - make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ - *helper = (make_cursor_helper_t){.ctor = _make_cmd_cursor_from_agg}; \ - TestSuite_AddFull(suite, prefix "/agg", fn, &bson_free, helper, TestSuite_CheckLive); \ - } else \ +#define TEST_CURSOR_AGG(prefix, fn) \ + if (1) { \ + make_cursor_helper_t *const helper = bson_malloc(sizeof(*helper)); \ + *helper = (make_cursor_helper_t){.ctor = _make_cmd_cursor_from_agg}; \ + TestSuite_AddFull(suite, prefix "/agg [lock:live-server]", fn, &bson_free, helper, TestSuite_CheckLive); \ + } else \ ((void)0) @@ -2394,9 +2394,14 @@ test_cursor_install(TestSuite *suite) TestSuite_AddLive(suite, "/Cursor/empty_collection", test_cursor_empty_collection); TestSuite_AddLive(suite, "/Cursor/new_from_agg", test_cursor_new_from_aggregate); TestSuite_AddLive(suite, "/Cursor/new_from_agg_no_initial", test_cursor_new_from_aggregate_no_initial); - TestSuite_AddFull(suite, "/Cursor/new_from_find", test_cursor_new_from_find, NULL, NULL, TestSuite_CheckLive); TestSuite_AddFull( - suite, "/Cursor/new_from_find_batches", test_cursor_new_from_find_batches, NULL, NULL, TestSuite_CheckLive); + suite, "/Cursor/new_from_find [lock:live-server]", test_cursor_new_from_find, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Cursor/new_from_find_batches [lock:live-server]", + test_cursor_new_from_find_batches, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddLive(suite, "/Cursor/new_invalid", test_cursor_new_invalid); TestSuite_AddMockServerTest(suite, "/Cursor/new_tailable_await", test_cursor_new_tailable_await); TestSuite_AddMockServerTest(suite, "/Cursor/int64_t_maxtimems", test_cursor_int64_t_maxtimems); diff --git a/src/libmongoc/tests/test-mongoc-cyrus.c b/src/libmongoc/tests/test-mongoc-cyrus.c index f3797ad68bc..8451a3d80c5 100644 --- a/src/libmongoc/tests/test-mongoc-cyrus.c +++ b/src/libmongoc/tests/test-mongoc-cyrus.c @@ -92,7 +92,7 @@ test_cyrus_install(TestSuite *suite) { TestSuite_Add(suite, "/SASL/properties", test_sasl_properties); TestSuite_AddFull(suite, - "/SASL/canonicalize", + "/SASL/canonicalize [lock:live-server]", test_sasl_canonicalize_hostname, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-database.c b/src/libmongoc/tests/test-mongoc-database.c index 94f1760c6e9..a3031b264e9 100644 --- a/src/libmongoc/tests/test-mongoc-database.c +++ b/src/libmongoc/tests/test-mongoc-database.c @@ -917,8 +917,12 @@ void test_database_install(TestSuite *suite) { TestSuite_AddMockServerTest(suite, "/Database/aggregate/inherit/database", test_aggregate_inherit_database); - TestSuite_AddFull( - suite, "/Database/create_with_write_concern", test_create_with_write_concern, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/Database/create_with_write_concern [lock:live-server]", + test_create_with_write_concern, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddLive(suite, "/Database/copy", test_copy); TestSuite_AddLive(suite, "/Database/has_collection", test_has_collection); TestSuite_AddMockServerTest( diff --git a/src/libmongoc/tests/test-mongoc-dns.c b/src/libmongoc/tests/test-mongoc-dns.c index 4668d41d8cb..22678a83ae5 100644 --- a/src/libmongoc/tests/test-mongoc-dns.c +++ b/src/libmongoc/tests/test-mongoc-dns.c @@ -1377,7 +1377,7 @@ test_dns_install(TestSuite *suite) TestSuite_AddFull( suite, "/initial_dns_seedlist_discovery/srv_polling/mocked", test_srv_polling_mocked, NULL, NULL, NULL); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/small_initial_buffer", + "/initial_dns_seedlist_discovery/small_initial_buffer [lock:live-server]", test_small_initial_buffer, NULL, NULL, @@ -1388,56 +1388,56 @@ test_dns_install(TestSuite *suite) * Records for mongos Discovery" spec, not the "Initial DNS Seedlist * Discovery" spec. */ TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_9/single", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_9/single [lock:live-server]", prose_test_9_single, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_9/pooled", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_9/pooled [lock:live-server]", prose_test_9_pooled, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_10/single", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_10/single [lock:live-server]", prose_test_10_single, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_10/pooled", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_10/pooled [lock:live-server]", prose_test_10_pooled, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_11/single", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_11/single [lock:live-server]", prose_test_11_single, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_11/pooled", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_11/pooled [lock:live-server]", prose_test_11_pooled, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_12/single", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_12/single [lock:live-server]", prose_test_12_single, NULL, NULL, test_dns_check_srv_polling); TestSuite_AddFull(suite, - "/initial_dns_seedlist_discovery/srv_polling/prose_test_12/pooled", + "/initial_dns_seedlist_discovery/srv_polling/prose_test_12/pooled [lock:live-server]", prose_test_12_pooled, NULL, NULL, @@ -1445,7 +1445,7 @@ test_dns_install(TestSuite *suite) TestSuite_AddFull( suite, - "/initial_dns_seedlist_discovery/srv_polling/removing_servers_closes_connections", + "/initial_dns_seedlist_discovery/srv_polling/removing_servers_closes_connections [lock:live-server]", test_removing_servers_closes_connections, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-exhaust.c b/src/libmongoc/tests/test-mongoc-exhaust.c index ffe6e5ee3c7..776e80a0c0f 100644 --- a/src/libmongoc/tests/test-mongoc-exhaust.c +++ b/src/libmongoc/tests/test-mongoc-exhaust.c @@ -768,17 +768,39 @@ test_exhaust_in_child(void) void test_exhaust_install(TestSuite *suite) { - TestSuite_AddFull(suite, "/Client/exhaust_cursor/works", test_exhaust_cursor_works, NULL, NULL, skip_if_no_exhaust); - TestSuite_AddFull( - suite, "/Client/exhaust_cursor/no_match", test_exhaust_cursor_no_match, NULL, NULL, skip_if_no_exhaust); - TestSuite_AddFull( - suite, "/Client/exhaust_cursor/single", test_exhaust_cursor_single, NULL, NULL, skip_if_no_exhaust); - TestSuite_AddFull(suite, "/Client/exhaust_cursor/pool", test_exhaust_cursor_pool, NULL, NULL, skip_if_no_exhaust); - TestSuite_AddFull( - suite, "/Client/exhaust_cursor/batches", test_exhaust_cursor_multi_batch, NULL, NULL, skip_if_no_exhaust); + TestSuite_AddFull(suite, + "/Client/exhaust_cursor/works [lock:live-server]", + test_exhaust_cursor_works, + NULL, + NULL, + skip_if_no_exhaust); + TestSuite_AddFull(suite, + "/Client/exhaust_cursor/no_match [lock:live-server]", + test_exhaust_cursor_no_match, + NULL, + NULL, + skip_if_no_exhaust); + TestSuite_AddFull(suite, + "/Client/exhaust_cursor/single [lock:live-server]", + test_exhaust_cursor_single, + NULL, + NULL, + skip_if_no_exhaust); + TestSuite_AddFull(suite, + "/Client/exhaust_cursor/pool [lock:live-server]", + test_exhaust_cursor_pool, + NULL, + NULL, + skip_if_no_exhaust); + TestSuite_AddFull(suite, + "/Client/exhaust_cursor/batches [lock:live-server]", + test_exhaust_cursor_multi_batch, + NULL, + NULL, + skip_if_no_exhaust); TestSuite_AddLive(suite, "/Client/set_max_await_time_ms", test_cursor_set_max_await_time_ms); TestSuite_AddFull(suite, - "/Client/exhaust_cursor/server_hint", + "/Client/exhaust_cursor/server_hint [lock:live-server]", test_cursor_server_hint_with_exhaust, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-find-and-modify.c b/src/libmongoc/tests/test-mongoc-find-and-modify.c index 115550c3243..80e8cc21c31 100644 --- a/src/libmongoc/tests/test-mongoc-find-and-modify.c +++ b/src/libmongoc/tests/test-mongoc-find-and-modify.c @@ -511,7 +511,7 @@ test_find_and_modify_install(TestSuite *suite) TestSuite_AddMockServerTest( suite, "/find_and_modify/find_and_modify/write_concern", test_find_and_modify_write_concern); TestSuite_AddFull(suite, - "/find_and_modify/find_and_modify/write_concern_failure", + "/find_and_modify/find_and_modify/write_concern_failure [lock:live-server]", test_find_and_modify_write_concern_failure, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-gridfs-bucket.c b/src/libmongoc/tests/test-mongoc-gridfs-bucket.c index 3cd48cdc79c..07116c4a7f1 100644 --- a/src/libmongoc/tests/test-mongoc-gridfs-bucket.c +++ b/src/libmongoc/tests/test-mongoc-gridfs-bucket.c @@ -1228,16 +1228,17 @@ test_gridfs_bucket_install(TestSuite *suite) test_all_spec_tests(suite); TestSuite_AddLive(suite, "/gridfs/create_bucket", test_create_bucket); TestSuite_AddLive(suite, "/gridfs/upload_and_download", test_upload_and_download); - TestSuite_AddFull(suite, "/gridfs/upload_error", test_upload_error, NULL, NULL, test_framework_skip_if_no_auth); + TestSuite_AddFull( + suite, "/gridfs/upload_error [lock:live-server]", test_upload_error, NULL, NULL, test_framework_skip_if_no_auth); TestSuite_AddFull(suite, - "/gridfs/find_w_session", + "/gridfs/find_w_session [lock:live-server]", test_find_w_session, NULL, NULL, test_framework_skip_if_no_sessions, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/gridfs/find", + "/gridfs/find [lock:live-server]", test_find, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-gridfs.c b/src/libmongoc/tests/test-mongoc-gridfs.c index 9a68462ec55..033c0d8157d 100644 --- a/src/libmongoc/tests/test-mongoc-gridfs.c +++ b/src/libmongoc/tests/test-mongoc-gridfs.c @@ -1618,11 +1618,19 @@ test_gridfs_install(TestSuite *suite) TestSuite_AddLive(suite, "/gridfs_old/write", test_write); TestSuite_AddLive(suite, "/gridfs_old/write_at_boundary", test_write_at_boundary); TestSuite_AddLive(suite, "/gridfs_old/write_past_end", test_write_past_end); - TestSuite_AddFull( - suite, "/gridfs_old/test_long_seek", test_long_seek, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/gridfs_old/test_long_seek [lock:live-server][timeout:30]", + test_long_seek, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/gridfs_old/remove_by_filename", test_remove_by_filename); - TestSuite_AddFull( - suite, "/gridfs_old/missing_chunk", test_missing_chunk, NULL, NULL, test_framework_skip_if_slow_or_live); + TestSuite_AddFull(suite, + "/gridfs_old/missing_chunk [lock:live-server][timeout:30]", + test_missing_chunk, + NULL, + NULL, + test_framework_skip_if_slow_or_live); TestSuite_AddLive(suite, "/gridfs_old/oversize_chunk", test_oversize); TestSuite_AddLive(suite, "/gridfs_old/missing_file", test_missing_file); TestSuite_AddLive(suite, "/gridfs_old/file_set_id", test_set_id); diff --git a/src/libmongoc/tests/test-mongoc-http.c b/src/libmongoc/tests/test-mongoc-http.c index 30ca457db11..816b4e94d32 100644 --- a/src/libmongoc/tests/test-mongoc-http.c +++ b/src/libmongoc/tests/test-mongoc-http.c @@ -88,9 +88,17 @@ test_mongoc_http_post(void *unused) void test_http_install(TestSuite *suite) { - TestSuite_AddFull( - suite, "/http/get", test_mongoc_http_get, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_offline); + TestSuite_AddFull(suite, + "/http/get [uses:simple-http-server-18000]", + test_mongoc_http_get, + NULL /* dtor */, + NULL /* ctx */, + test_framework_skip_if_offline); - TestSuite_AddFull( - suite, "/http/post", test_mongoc_http_post, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_offline); + TestSuite_AddFull(suite, + "/http/post [uses:simple-http-server-18000]", + test_mongoc_http_post, + NULL /* dtor */, + NULL /* ctx */, + test_framework_skip_if_offline); } diff --git a/src/libmongoc/tests/test-mongoc-loadbalanced.c b/src/libmongoc/tests/test-mongoc-loadbalanced.c index f793bfc2477..5ebd33aa1d6 100644 --- a/src/libmongoc/tests/test-mongoc-loadbalanced.c +++ b/src/libmongoc/tests/test-mongoc-loadbalanced.c @@ -832,47 +832,47 @@ void test_loadbalanced_install(TestSuite *suite) { TestSuite_AddFull(suite, - "/loadbalanced/sessions/supported", + "/loadbalanced/sessions/supported [lock:live-server]", test_loadbalanced_sessions_supported, NULL /* ctx */, NULL /* dtor */, skip_if_not_loadbalanced); TestSuite_AddFull(suite, - "/loadbalanced/sessions/do_not_expire", + "/loadbalanced/sessions/do_not_expire [lock:live-server]", test_loadbalanced_sessions_do_not_expire, NULL /* ctx */, NULL /* dtor */, skip_if_not_loadbalanced); TestSuite_AddFull(suite, - "/loadbalanced/client_uri_validation", + "/loadbalanced/client_uri_validation [lock:live-server]", test_loadbalanced_client_uri_validation, NULL /* ctx */, NULL /* dtor */, NULL); TestSuite_AddFull(suite, - "/loadbalanced/connect/single", + "/loadbalanced/connect/single [lock:live-server]", test_loadbalanced_connect_single, NULL /* ctx */, NULL /* dtor */, skip_if_not_loadbalanced); TestSuite_AddFull(suite, - "/loadbalanced/connect/pooled", + "/loadbalanced/connect/pooled [lock:live-server]", test_loadbalanced_connect_pooled, NULL /* ctx */, NULL /* dtor */, skip_if_not_loadbalanced); TestSuite_AddFull(suite, - "/loadbalanced/server_selection_establishes_connection/single", + "/loadbalanced/server_selection_establishes_connection/single [lock:live-server]", test_loadbalanced_server_selection_establishes_connection_single, NULL /* ctx */, NULL /* dtor */, skip_if_not_loadbalanced); TestSuite_AddFull(suite, - "/loadbalanced/cooldown_is_bypassed/single", + "/loadbalanced/cooldown_is_bypassed/single [lock:live-server]", test_loadbalanced_cooldown_is_bypassed_single, NULL /* dtor */, NULL /* ctx */, @@ -892,7 +892,7 @@ test_loadbalanced_install(TestSuite *suite) suite, "/loadbalanced/post_handshake_error_clears_pool", test_post_handshake_error_clears_pool); TestSuite_AddFull(suite, - "/loadbalanced/sends_recoveryToken", + "/loadbalanced/sends_recoveryToken [lock:live-server]", test_loadbalanced_sends_recoveryToken, NULL /* ctx */, NULL /* dtor */, diff --git a/src/libmongoc/tests/test-mongoc-long-namespace.c b/src/libmongoc/tests/test-mongoc-long-namespace.c index 95b507134ba..19456850df4 100644 --- a/src/libmongoc/tests/test-mongoc-long-namespace.c +++ b/src/libmongoc/tests/test-mongoc-long-namespace.c @@ -459,22 +459,24 @@ test_long_namespace_install(TestSuite *suite) /* MongoDB 4.4 (wire version 9) introduced support for long namespaces in * SERVER-32959 */ - add_long_namespace_test("/long_namespace/crud", crud, test_framework_skip_if_max_wire_version_less_than_9); + add_long_namespace_test( + "/long_namespace/crud [lock:live-server]", crud, test_framework_skip_if_max_wire_version_less_than_9); - add_long_namespace_test("/long_namespace/getmore", getmore, test_framework_skip_if_max_wire_version_less_than_9); + add_long_namespace_test( + "/long_namespace/getmore [lock:live-server]", getmore, test_framework_skip_if_max_wire_version_less_than_9); - add_long_namespace_test("/long_namespace/change_stream", + add_long_namespace_test("/long_namespace/change_stream [lock:live-server]", change_stream, test_framework_skip_if_not_rs_version_9, test_framework_skip_if_no_sessions); - add_long_namespace_test("/long_namespace/collection_rename", + add_long_namespace_test("/long_namespace/collection_rename [lock:live-server]", collection_rename, test_framework_skip_if_max_wire_version_less_than_9, test_framework_skip_if_mongos); TestSuite_AddFull(suite, - "/long_namespace/unsupported_long_coll", + "/long_namespace/unsupported_long_coll [lock:live-server]", unsupported_long_coll, NULL /* dtor */, NULL /* ctx */, diff --git a/src/libmongoc/tests/test-mongoc-max-staleness.c b/src/libmongoc/tests/test-mongoc-max-staleness.c index 17d207b17ad..20750b73aaa 100644 --- a/src/libmongoc/tests/test-mongoc-max-staleness.c +++ b/src/libmongoc/tests/test-mongoc-max-staleness.c @@ -339,23 +339,27 @@ test_client_max_staleness_install(TestSuite *suite) TestSuite_Add(suite, "/Client/max_staleness", test_mongoc_client_max_staleness); TestSuite_AddMockServerTest(suite, "/Client/max_staleness/mongos", test_mongos_max_staleness_read_pref); TestSuite_AddFull(suite, - "/Client/last_write_date", + "/Client/last_write_date [lock:live-server][timeout:30]", test_last_write_date, NULL, NULL, test_framework_skip_if_not_replset, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Client/last_write_date/pooled", + "/Client/last_write_date/pooled [lock:live-server][timeout:30]", test_last_write_date_pooled, NULL, NULL, test_framework_skip_if_not_replset, test_framework_skip_if_slow); - TestSuite_AddFull( - suite, "/Client/last_write_date_absent", test_last_write_date_absent, NULL, NULL, test_framework_skip_if_replset); TestSuite_AddFull(suite, - "/Client/last_write_date_absent/pooled", + "/Client/last_write_date_absent [lock:live-server]", + test_last_write_date_absent, + NULL, + NULL, + test_framework_skip_if_replset); + TestSuite_AddFull(suite, + "/Client/last_write_date_absent/pooled [lock:live-server]", test_last_write_date_absent_pooled, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-mongos-pinning.c b/src/libmongoc/tests/test-mongoc-mongos-pinning.c index 404e34569eb..19817d339c4 100644 --- a/src/libmongoc/tests/test-mongoc-mongos-pinning.c +++ b/src/libmongoc/tests/test-mongoc-mongos-pinning.c @@ -169,7 +169,7 @@ void test_mongos_pinning_install(TestSuite *suite) { TestSuite_AddFull(suite, - "/mongos_pinning/new_transaction_unpins", + "/mongos_pinning/new_transaction_unpins [lock:live-server]", test_new_transaction_unpins, NULL, NULL, @@ -178,7 +178,7 @@ test_mongos_pinning_install(TestSuite *suite) test_framework_skip_if_not_mongos); TestSuite_AddFull(suite, - "/mongos_pinning/non_transaction_unpins", + "/mongos_pinning/non_transaction_unpins [lock:live-server]", test_non_transaction_unpins, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-primary-stepdown.c b/src/libmongoc/tests/test-mongoc-primary-stepdown.c index dcc0935d28a..10053fe90a0 100644 --- a/src/libmongoc/tests/test-mongoc-primary-stepdown.c +++ b/src/libmongoc/tests/test-mongoc-primary-stepdown.c @@ -422,14 +422,14 @@ test_primary_stepdown_install(TestSuite *suite) #define TestPooledAndSingle(name, fn) \ if (1) { \ TestSuite_AddFull(suite, \ - name "/single", \ + name "/single [lock:live-server]", \ fn, \ NULL, \ &single_ctx, \ test_framework_skip_if_auth, \ test_framework_skip_if_not_replset); \ TestSuite_AddFull(suite, \ - name "/pooled", \ + name "/pooled [lock:live-server]", \ fn, \ NULL, \ &pooled_ctx, \ diff --git a/src/libmongoc/tests/test-mongoc-retryable-reads.c b/src/libmongoc/tests/test-mongoc-retryable-reads.c index 597dfe9bc2f..74d277f768b 100644 --- a/src/libmongoc/tests/test-mongoc-retryable-reads.c +++ b/src/libmongoc/tests/test-mongoc-retryable-reads.c @@ -564,28 +564,28 @@ test_retryable_reads_install(TestSuite *suite) { test_all_spec_tests(suite); TestSuite_AddFull(suite, - "/retryable_reads/cmd_helpers", + "/retryable_reads/cmd_helpers [lock:live-server]", test_cmd_helpers, NULL, NULL, test_framework_skip_if_mongos, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/retryable_reads/retry_off", + "/retryable_reads/retry_off [lock:live-server]", test_retry_reads_off, NULL, NULL, test_framework_skip_if_mongos, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/retryable_reads/sharded/on_other_mongos", + "/retryable_reads/sharded/on_other_mongos [lock:live-server]", test_retry_reads_sharded_on_other_mongos, NULL, NULL, test_framework_skip_if_not_mongos, test_framework_skip_if_no_failpoint); TestSuite_AddFull(suite, - "/retryable_reads/sharded/on_same_mongos", + "/retryable_reads/sharded/on_same_mongos [lock:live-server]", test_retry_reads_sharded_on_same_mongos, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-retryable-writes.c b/src/libmongoc/tests/test-mongoc-retryable-writes.c index 3f14e89c705..a2a49badaab 100644 --- a/src/libmongoc/tests/test-mongoc-retryable-writes.c +++ b/src/libmongoc/tests/test-mongoc-retryable-writes.c @@ -1236,7 +1236,7 @@ test_retryable_writes_install(TestSuite *suite) test_all_spec_tests(suite); TestSuite_AddMockServerTest(suite, "/retryable_writes/failover", test_rs_failover, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/command_with_opts", + "/retryable_writes/command_with_opts [lock:live-server]", test_command_with_opts, NULL, NULL, @@ -1259,21 +1259,25 @@ test_retryable_writes_install(TestSuite *suite) "/retryable_writes/bulk_operation_execute_unacknowledged", test_bulk_operation_execute_unacknowledged, test_framework_skip_if_no_crypto); - TestSuite_AddFull( - suite, "/retryable_writes/no_crypto", test_retry_no_crypto, NULL, NULL, test_framework_skip_if_crypto); + TestSuite_AddFull(suite, + "/retryable_writes/no_crypto [lock:live-server]", + test_retry_no_crypto, + NULL, + NULL, + test_framework_skip_if_crypto); TestSuite_AddMockServerTest(suite, "/retryable_writes/unsupported_storage_engine_error", test_unsupported_storage_engine_error, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/bulk_tracks_new_server", + "/retryable_writes/bulk_tracks_new_server [lock:live-server]", test_bulk_retry_tracks_new_server, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_not_replset, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_3", + "/retryable_writes/prose_test_3 [lock:live-server]", retryable_writes_prose_test_3, NULL, NULL, @@ -1281,7 +1285,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_17, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_3/find_modify", + "/retryable_writes/prose_test_3/find_modify [lock:live-server]", retryable_writes_original_error_find_modify, NULL, NULL, @@ -1289,7 +1293,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_17, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_3/general_command", + "/retryable_writes/prose_test_3/general_command [lock:live-server]", retryable_writes_original_error_general_command, NULL, NULL, @@ -1297,7 +1301,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_17, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_3/bulkwrite", + "/retryable_writes/prose_test_3/bulkwrite [lock:live-server]", retryable_writes_original_error_bulkwrite, NULL, NULL, @@ -1305,7 +1309,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_25, // require server 8.0 test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_4/insert", + "/retryable_writes/prose_test_4/insert [lock:live-server]", retryable_writes_sharded_on_other_mongos_insert, NULL, NULL, @@ -1315,7 +1319,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_9, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_4/bulkwrite", + "/retryable_writes/prose_test_4/bulkwrite [lock:live-server]", retryable_writes_sharded_on_other_mongos_bulkWrite, NULL, NULL, @@ -1324,7 +1328,7 @@ test_retryable_writes_install(TestSuite *suite) test_framework_skip_if_max_wire_version_less_than_25, // require server 8.0 test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/retryable_writes/prose_test_5", + "/retryable_writes/prose_test_5 [lock:live-server]", retryable_writes_sharded_on_same_mongos, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-sample-commands.c b/src/libmongoc/tests/test-mongoc-sample-commands.c index eea80d65e0e..7fe8d6603d6 100644 --- a/src/libmongoc/tests/test-mongoc-sample-commands.c +++ b/src/libmongoc/tests/test-mongoc-sample-commands.c @@ -4463,5 +4463,6 @@ void test_samples_install(TestSuite *suite) { TestSuite_AddLive(suite, "/Samples", test_sample_commands); - TestSuite_AddFull(suite, "/Samples/with_txn", test_with_txn_example, NULL, NULL, test_framework_skip_if_no_txns); + TestSuite_AddFull( + suite, "/Samples/with_txn [lock:live-server]", test_with_txn_example, NULL, NULL, test_framework_skip_if_no_txns); } diff --git a/src/libmongoc/tests/test-mongoc-scram.c b/src/libmongoc/tests/test-mongoc-scram.c index 9553bec77b0..7eb25f0f962 100644 --- a/src/libmongoc/tests/test-mongoc-scram.c +++ b/src/libmongoc/tests/test-mongoc-scram.c @@ -749,14 +749,14 @@ test_scram_install(TestSuite *suite) TestSuite_Add(suite, "/scram/utf8_to_unicode", test_mongoc_utf8_to_unicode); #endif TestSuite_AddFull(suite, - "/scram/cache_invalidation", + "/scram/cache_invalidation [lock:live-server]", test_mongoc_scram_cache_invalidation, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_macos); // CDRIVER-6079 TestSuite_AddFull(suite, - "/scram/auth_tests", + "/scram/auth_tests [lock:live-server]", test_mongoc_scram_auth, NULL /* dtor */, NULL /* ctx */, @@ -764,7 +764,7 @@ test_scram_install(TestSuite *suite) _skip_if_no_sha256, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/scram/saslprep_auth", + "/scram/saslprep_auth [lock:live-server]", test_mongoc_saslprep_auth, NULL /* dtor */, NULL /* ctx */, @@ -772,7 +772,7 @@ test_scram_install(TestSuite *suite) _skip_if_no_sha256, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/scram/empty_password", + "/scram/empty_password [lock:live-server]", test_mongoc_scram_empty_password, NULL /* dtor */, NULL /* ctx */, diff --git a/src/libmongoc/tests/test-mongoc-sdam.c b/src/libmongoc/tests/test-mongoc-sdam.c index 64736ab8b40..398b24de2d3 100644 --- a/src/libmongoc/tests/test-mongoc-sdam.c +++ b/src/libmongoc/tests/test-mongoc-sdam.c @@ -1001,28 +1001,28 @@ test_sdam_install(TestSuite *suite) { test_all_spec_tests(suite); TestSuite_AddFull(suite, - "/server_discovery_and_monitoring/topology/discovery", + "/server_discovery_and_monitoring/topology/discovery [lock:live-server]", test_topology_discovery, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/server_discovery_and_monitoring/directconnection", + "/server_discovery_and_monitoring/directconnection [lock:live-server]", test_direct_connection, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/server_discovery_and_monitoring/existing/behavior", + "/server_discovery_and_monitoring/existing/behavior [lock:live-server]", test_existing_behavior, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_not_replset); TestSuite_AddFull(suite, - "/server_discovery_and_monitoring/prose/rtt", + "/server_discovery_and_monitoring/prose/rtt [lock:live-server]", test_prose_rtt, NULL /* dtor */, NULL /* ctx */, test_framework_skip_if_max_wire_version_less_than_9); - TestSuite_Add(suite, "/server_discovery_and_monitoring/prose/heartbeat", test_prose_heartbeat); + TestSuite_Add(suite, "/server_discovery_and_monitoring/prose/heartbeat [lock:live-server]", test_prose_heartbeat); } diff --git a/src/libmongoc/tests/test-mongoc-server-selection-errors.c b/src/libmongoc/tests/test-mongoc-server-selection-errors.c index 2cdd26d3220..2b0163ecf8c 100644 --- a/src/libmongoc/tests/test-mongoc-server-selection-errors.c +++ b/src/libmongoc/tests/test-mongoc-server-selection-errors.c @@ -293,7 +293,7 @@ test_server_selection_errors_install(TestSuite *suite) { TestSuite_Add(suite, "/server_selection/errors/dns/direct/single", test_server_selection_error_dns_direct_single); TestSuite_AddFull(suite, - "/server_selection/errors/dns/direct/pooled", + "/server_selection/errors/dns/direct/pooled [timeout:30]", test_server_selection_error_dns_direct_pooled, NULL, NULL, @@ -301,43 +301,43 @@ test_server_selection_errors_install(TestSuite *suite) TestSuite_Add( suite, "/server_selection/errors/dns/multi/fail/single", test_server_selection_error_dns_multi_fail_single); TestSuite_AddFull(suite, - "/server_selection/errors/dns/multi/fail/pooled", + "/server_selection/errors/dns/multi/fail/pooled [lock:live-server][timeout:30]", test_server_selection_error_dns_multi_fail_pooled, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/server_selection/errors/dns/multi/success/single", + "/server_selection/errors/dns/multi/success/single [lock:live-server]", test_server_selection_error_dns_multi_success_single, NULL, NULL, test_framework_skip_if_single); TestSuite_AddFull(suite, - "/server_selection/errors/dns/multi/success/pooled", + "/server_selection/errors/dns/multi/success/pooled [lock:live-server]", test_server_selection_error_dns_multi_success_pooled, NULL, NULL, test_framework_skip_if_single); TestSuite_AddFull(suite, - "/server_selection/errors/uds/auth_failure/single", + "/server_selection/errors/uds/auth_failure/single [lock:live-server]", test_server_selection_uds_auth_failure_single, NULL, NULL, test_framework_skip_if_no_uds); TestSuite_AddFull(suite, - "/server_selection/errors/uds/auth_failure/pooled", + "/server_selection/errors/uds/auth_failure/pooled [lock:live-server]", test_server_selection_uds_auth_failure_pooled, NULL, NULL, test_framework_skip_if_no_uds); TestSuite_AddFull(suite, - "/server_selection/errors/uds/not_found/single", + "/server_selection/errors/uds/not_found/single [lock:live-server]", test_server_selection_uds_not_found_single, NULL, NULL, test_framework_skip_if_windows); TestSuite_AddFull(suite, - "/server_selection/errors/uds/not_found/pooled", + "/server_selection/errors/uds/not_found/pooled [lock:live-server]", test_server_selection_uds_not_found_pooled, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-socket.c b/src/libmongoc/tests/test-mongoc-socket.c index 037d67aaee4..ec48354ef29 100644 --- a/src/libmongoc/tests/test-mongoc-socket.c +++ b/src/libmongoc/tests/test-mongoc-socket.c @@ -459,8 +459,14 @@ void test_socket_install(TestSuite *suite) { TestSuite_Add(suite, "/Socket/check_closed", test_mongoc_socket_check_closed); - TestSuite_AddFull(suite, "/Socket/timed_out", test_mongoc_socket_timed_out, NULL, NULL, test_framework_skip_if_slow); - TestSuite_AddFull(suite, "/Socket/sendv", test_mongoc_socket_sendv, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull( - suite, "/Socket/connect_refusal", test_mongoc_socket_poll_refusal, NULL, NULL, test_framework_skip_if_slow); + suite, "/Socket/timed_out [timeout:30]", test_mongoc_socket_timed_out, NULL, NULL, test_framework_skip_if_slow); + TestSuite_AddFull( + suite, "/Socket/sendv [timeout:30]", test_mongoc_socket_sendv, NULL, NULL, test_framework_skip_if_slow); + TestSuite_AddFull(suite, + "/Socket/connect_refusal [timeout:30]", + test_mongoc_socket_poll_refusal, + NULL, + NULL, + test_framework_skip_if_slow); } diff --git a/src/libmongoc/tests/test-mongoc-topology-reconcile.c b/src/libmongoc/tests/test-mongoc-topology-reconcile.c index ab33d8eb065..15391483fbb 100644 --- a/src/libmongoc/tests/test-mongoc-topology-reconcile.c +++ b/src/libmongoc/tests/test-mongoc-topology-reconcile.c @@ -638,20 +638,28 @@ test_topology_reconcile_add_single(void) void test_topology_reconcile_install(TestSuite *suite) { - TestSuite_AddMockServerTest( - suite, "/TOPOLOGY/reconcile/rs/pooled", test_topology_reconcile_rs_pooled, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/TOPOLOGY/reconcile/rs/single", test_topology_reconcile_rs_single, test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/TOPOLOGY/reconcile/rs/pooled [timeout:30]", + test_topology_reconcile_rs_pooled, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/TOPOLOGY/reconcile/rs/single [timeout:30]", + test_topology_reconcile_rs_single, + test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, "/TOPOLOGY/reconcile/sharded/pooled", test_topology_reconcile_sharded_pooled); TestSuite_AddMockServerTest(suite, "/TOPOLOGY/reconcile/sharded/single", test_topology_reconcile_sharded_single); TestSuite_AddFull(suite, - "/TOPOLOGY/reconcile/from_handshake", + "/TOPOLOGY/reconcile/from_handshake [lock:live-server]", test_topology_reconcile_from_handshake, NULL, NULL, test_framework_skip_if_not_replset); - TestSuite_AddMockServerTest( - suite, "/TOPOLOGY/reconcile/retire/single", test_topology_reconcile_retire_single, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/TOPOLOGY/reconcile/add/single", test_topology_reconcile_add_single, test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/TOPOLOGY/reconcile/retire/single [timeout:30]", + test_topology_reconcile_retire_single, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/TOPOLOGY/reconcile/add/single [timeout:30]", + test_topology_reconcile_add_single, + test_framework_skip_if_slow); } diff --git a/src/libmongoc/tests/test-mongoc-topology-scanner.c b/src/libmongoc/tests/test-mongoc-topology-scanner.c index 9a33801cb0d..b81e90ad3ee 100644 --- a/src/libmongoc/tests/test-mongoc-topology-scanner.c +++ b/src/libmongoc/tests/test-mongoc-topology-scanner.c @@ -5,6 +5,10 @@ #include #include +#if defined(MONGOC_ENABLE_SSL_OPENSSL) +#include +#endif + #include #include @@ -71,6 +75,9 @@ _test_topology_scanner(bool with_ssl) copt.weak_cert_validation = 1; mongoc_topology_scanner_set_ssl_opts(topology_scanner, &copt); +#if defined(MONGOC_ENABLE_SSL_OPENSSL) && OPENSSL_VERSION_NUMBER >= 0x10100000L + topology_scanner->openssl_ctx = _mongoc_openssl_ctx_new(&copt); +#endif } #endif @@ -710,13 +717,13 @@ test_topology_scanner_install(TestSuite *suite) suite, "/TOPOLOGY/dns", test_topology_scanner_dns, test_framework_skip_if_no_dual_ip_hostname); TestSuite_AddMockServerTest(suite, "/TOPOLOGY/retired_fails_to_initiate", test_topology_retired_fails_to_initiate); TestSuite_AddFull(suite, - "/TOPOLOGY/scanner/renegotiate/single", + "/TOPOLOGY/scanner/renegotiate/single [lock:live-server][timeout:30]", test_topology_scanner_does_not_renegotiate_single, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/TOPOLOGY/scanner/renegotiate/pooled", + "/TOPOLOGY/scanner/renegotiate/pooled [lock:live-server][timeout:30]", test_topology_scanner_does_not_renegotiate_pooled, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-topology.c b/src/libmongoc/tests/test-mongoc-topology.c index dd16d10e851..80da044dbef 100644 --- a/src/libmongoc/tests/test-mongoc-topology.c +++ b/src/libmongoc/tests/test-mongoc-topology.c @@ -2607,89 +2607,102 @@ test_topology_install(TestSuite *suite) TestSuite_AddLive(suite, "/Topology/client_pool_creation", test_topology_client_pool_creation); TestSuite_AddLive(suite, "/Topology/start_stop", test_topology_thread_start_stop); TestSuite_AddFull(suite, - "/Topology/server_selection_try_once_option", + "/Topology/server_selection_try_once_option [lock:live-server][timeout:30]", test_server_selection_try_once_option, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Topology/server_selection_try_once", + "/Topology/server_selection_try_once [lock:live-server][timeout:30]", test_server_selection_try_once, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Topology/server_selection_try_once_false", + "/Topology/server_selection_try_once_false [lock:live-server][timeout:30]", test_server_selection_try_once_false, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddFull(suite, - "/Topology/invalidate_server/single", + "/Topology/invalidate_server/single [lock:live-server][timeout:30]", test_topology_invalidate_server_single, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/Topology/invalidate_server/pooled", + "/Topology/invalidate_server/pooled [lock:live-server][timeout:30]", test_topology_invalidate_server_pooled, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/Topology/invalid_cluster_node", + "/Topology/invalid_cluster_node [lock:live-server][timeout:30]", test_invalid_cluster_node, NULL, NULL, test_framework_skip_if_slow_or_live); TestSuite_AddFull(suite, - "/Topology/max_wire_version_race_condition", + "/Topology/max_wire_version_race_condition [lock:live-server]", test_max_wire_version_race_condition, NULL, NULL, test_framework_skip_if_no_auth); + TestSuite_AddMockServerTest(suite, + "/Topology/cooldown/standalone [timeout:30]", + test_cooldown_standalone, + NULL, + NULL, + test_framework_skip_if_slow); TestSuite_AddMockServerTest( - suite, "/Topology/cooldown/standalone", test_cooldown_standalone, NULL, NULL, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Topology/cooldown/rs", test_cooldown_rs, NULL, NULL, test_framework_skip_if_slow); + suite, "/Topology/cooldown/rs [timeout:30]", test_cooldown_rs, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddMockServerTest( - suite, "/Topology/cooldown/retry", test_cooldown_retry, NULL, NULL, test_framework_skip_if_slow); + suite, "/Topology/cooldown/retry [timeout:30]", test_cooldown_retry, NULL, NULL, test_framework_skip_if_slow); TestSuite_Add(suite, "/Topology/multiple_selection_errors", test_multiple_selection_errors); TestSuite_AddMockServerTest(suite, "/Topology/connect_timeout/succeed", test_select_after_timeout); TestSuite_AddMockServerTest(suite, "/Topology/try_once/succeed", test_select_after_try_once); TestSuite_AddLive(suite, "/Topology/invalid_server_id", test_invalid_server_id); TestSuite_AddMockServerTest(suite, "/Topology/server_removed/single", test_server_removed_during_handshake_single); TestSuite_AddMockServerTest(suite, "/Topology/server_removed/pooled", test_server_removed_during_handshake_pooled); - TestSuite_AddFull(suite, "/Topology/rtt", test_rtt, NULL, NULL, test_framework_skip_if_slow); + TestSuite_AddFull( + suite, "/Topology/rtt [lock:live-server][timeout:30]", test_rtt, NULL, NULL, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, "/Topology/add_and_scan_failure", test_add_and_scan_failure); - TestSuite_AddMockServerTest( - suite, "/Topology/hello_retry/single/hangup", test_hello_retry_single_hangup, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Topology/hello_retry/single/timeout", test_hello_retry_single_timeout, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Topology/hello_retry/single/hangup/fail", + "/Topology/hello_retry/single/hangup [timeout:30]", + test_hello_retry_single_hangup, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Topology/hello_retry/single/timeout [timeout:30]", + test_hello_retry_single_timeout, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Topology/hello_retry/single/hangup/fail [timeout:30]", test_hello_retry_single_hangup_fail, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Topology/hello_retry/single/timeout/fail", + "/Topology/hello_retry/single/timeout/fail [timeout:30]", test_hello_retry_single_timeout_fail, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Topology/hello_retry/pooled/hangup", test_hello_retry_pooled_hangup, test_framework_skip_if_slow); - TestSuite_AddMockServerTest( - suite, "/Topology/hello_retry/pooled/timeout", test_hello_retry_pooled_timeout, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Topology/hello_retry/pooled/hangup/fail", + "/Topology/hello_retry/pooled/hangup [timeout:30]", + test_hello_retry_pooled_hangup, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Topology/hello_retry/pooled/timeout [timeout:30]", + test_hello_retry_pooled_timeout, + test_framework_skip_if_slow); + TestSuite_AddMockServerTest(suite, + "/Topology/hello_retry/pooled/hangup/fail [timeout:30]", test_hello_retry_pooled_hangup_fail, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Topology/hello_retry/pooled/timeout/fail", + "/Topology/hello_retry/pooled/timeout/fail [timeout:30]", test_hello_retry_pooled_timeout_fail, test_framework_skip_if_slow); TestSuite_AddMockServerTest( - suite, "/Topology/incompatible_error", test_incompatible_error, test_framework_skip_if_slow); + suite, "/Topology/incompatible_error [timeout:30]", test_incompatible_error, test_framework_skip_if_slow); TestSuite_AddMockServerTest(suite, - "/Topology/compatible_null_error_pointer", + "/Topology/compatible_null_error_pointer [timeout:30]", test_compatible_null_error_pointer, test_framework_skip_if_slow); TestSuite_AddMockServerTest( @@ -2704,5 +2717,5 @@ test_topology_install(TestSuite *suite) TestSuite_AddMockServerTest(suite, "/Topology/hello_ok/single", test_hello_ok_single); TestSuite_AddMockServerTest(suite, "/Topology/hello_ok/pooled", test_hello_ok_pooled); TestSuite_AddMockServerTest(suite, "/Topology/failure_to_setup_after_retry", test_failure_to_setup_after_retry); - TestSuite_Add(suite, "/Topology/detect_nongenuine_hosts", test_detect_nongenuine_hosts); + TestSuite_Add(suite, "/Topology/detect_nongenuine_hosts [lock:live-server]", test_detect_nongenuine_hosts); } diff --git a/src/libmongoc/tests/test-mongoc-transactions.c b/src/libmongoc/tests/test-mongoc-transactions.c index 6fe63d1ac37..3cc292955ed 100644 --- a/src/libmongoc/tests/test-mongoc-transactions.c +++ b/src/libmongoc/tests/test-mongoc-transactions.c @@ -1044,10 +1044,18 @@ test_transactions_install(TestSuite *suite) test_framework_skip_if_no_txns, test_framework_skip_if_slow); - TestSuite_AddFull( - suite, "/transactions/supported", test_transactions_supported, NULL, NULL, test_framework_skip_if_no_txns); - TestSuite_AddFull( - suite, "/transactions/in_transaction", test_in_transaction, NULL, NULL, test_framework_skip_if_no_txns); + TestSuite_AddFull(suite, + "/transactions/supported [lock:live-server]", + test_transactions_supported, + NULL, + NULL, + test_framework_skip_if_no_txns); + TestSuite_AddFull(suite, + "/transactions/in_transaction [lock:live-server]", + test_in_transaction, + NULL, + NULL, + test_framework_skip_if_no_txns); TestSuite_AddMockServerTest( suite, "/transactions/server_selection_err", test_server_selection_error, test_framework_skip_if_no_crypto); TestSuite_AddMockServerTest( @@ -1055,15 +1063,19 @@ test_transactions_install(TestSuite *suite) TestSuite_AddMockServerTest( suite, "/transactions/unknown_commit_result", test_unknown_commit_result, test_framework_skip_if_no_crypto); TestSuite_AddFull(suite, - "/transactions/cursor_primary_read_pref", + "/transactions/cursor_primary_read_pref [lock:live-server]", test_cursor_primary_read_pref, NULL, NULL, test_framework_skip_if_no_txns); - TestSuite_AddFull( - suite, "/transactions/inherit_from_client", test_inherit_from_client, NULL, NULL, test_framework_skip_if_no_txns); TestSuite_AddFull(suite, - "/transactions/recovery_token_cleared", + "/transactions/inherit_from_client [lock:live-server]", + test_inherit_from_client, + NULL, + NULL, + test_framework_skip_if_no_txns); + TestSuite_AddFull(suite, + "/transactions/recovery_token_cleared [lock:live-server]", test_transaction_recovery_token_cleared, NULL, NULL, @@ -1071,7 +1083,7 @@ test_transactions_install(TestSuite *suite) test_framework_skip_if_no_crypto, test_framework_skip_if_not_mongos); TestSuite_AddFull(suite, - "/transactions/selected_server_pinned_to_mongos", + "/transactions/selected_server_pinned_to_mongos [lock:live-server]", test_selected_server_is_pinned_to_mongos, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-with-transaction.c b/src/libmongoc/tests/test-mongoc-with-transaction.c index 6a3952f20d8..84a73cc3e13 100644 --- a/src/libmongoc/tests/test-mongoc-with-transaction.c +++ b/src/libmongoc/tests/test-mongoc-with-transaction.c @@ -84,7 +84,7 @@ void test_with_transaction_install(TestSuite *suite) { TestSuite_AddFull(suite, - "/with_transaction/timeout_tests", + "/with_transaction/timeout_tests [lock:live-server]", test_with_transaction_timeout, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-write-commands.c b/src/libmongoc/tests/test-mongoc-write-commands.c index ff1c5fa8945..e388f72cf88 100644 --- a/src/libmongoc/tests/test-mongoc-write-commands.c +++ b/src/libmongoc/tests/test-mongoc-write-commands.c @@ -455,10 +455,15 @@ test_write_command_install(TestSuite *suite) TestSuite_AddLive(suite, "/WriteCommand/split_insert", test_split_insert); TestSuite_AddLive(suite, "/WriteCommand/bypass_not_sent", test_bypass_not_sent); TestSuite_AddLive(suite, "/WriteCommand/invalid_write_concern", test_invalid_write_concern); - TestSuite_AddFull(suite, "/WriteCommand/bypass_validation", test_bypass_validation, NULL, NULL, TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/WriteCommand/bypass_validation [lock:live-server]", + test_bypass_validation, + NULL, + NULL, + TestSuite_CheckLive); TestSuite_AddMockServerTest(suite, "/WriteCommand/insert_disconnect_mid_batch", test_disconnect_mid_batch); TestSuite_AddFull(suite, - "/WriteCommand/invalid_wc_server_error", + "/WriteCommand/invalid_wc_server_error [lock:live-server]", _test_invalid_wc_server_error, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-write-concern.c b/src/libmongoc/tests/test-mongoc-write-concern.c index ddd254bcb84..6eebed5a13c 100644 --- a/src/libmongoc/tests/test-mongoc-write-concern.c +++ b/src/libmongoc/tests/test-mongoc-write-concern.c @@ -613,16 +613,21 @@ test_write_concern_install(TestSuite *suite) TestSuite_Add(suite, "/WriteConcern/wtimeout_preserved", test_write_concern_wtimeout_preserved); TestSuite_AddMockServerTest(suite, "/WriteConcern", test_write_concern); TestSuite_AddLive(suite, "/WriteConcern/unacknowledged", test_write_concern_unacknowledged); - TestSuite_AddFull(suite, "/WriteConcern/inherited_fam", test_fam_no_session_no_txn, NULL, NULL, TestSuite_CheckLive); TestSuite_AddFull(suite, - "/WriteConcern/inherited_fam_session_no_txn", + "/WriteConcern/inherited_fam [lock:live-server]", + test_fam_no_session_no_txn, + NULL, + NULL, + TestSuite_CheckLive); + TestSuite_AddFull(suite, + "/WriteConcern/inherited_fam_session_no_txn [lock:live-server]", test_fam_session_no_txn, NULL, NULL, test_framework_skip_if_no_sessions, test_framework_skip_if_no_txns); TestSuite_AddFull(suite, - "/WriteConcern/inherited_fam_txn", + "/WriteConcern/inherited_fam_txn [lock:live-server]", test_fam_session_txn, NULL, NULL, diff --git a/src/libmongoc/tests/test-mongoc-x509.c b/src/libmongoc/tests/test-mongoc-x509.c index 0e73a844015..11135e667af 100644 --- a/src/libmongoc/tests/test-mongoc-x509.c +++ b/src/libmongoc/tests/test-mongoc-x509.c @@ -593,13 +593,13 @@ test_x509_install(TestSuite *suite) { #ifdef MONGOC_ENABLE_SSL TestSuite_AddFull(suite, - "/X509/auth", + "/X509/auth [lock:live-server]", test_x509_auth, NULL, NULL, test_framework_skip_if_no_auth, test_framework_skip_if_no_server_ssl); - TestSuite_AddFull(suite, "/X509/crl", test_crl, NULL, NULL, test_framework_skip_if_no_server_ssl); + TestSuite_AddFull(suite, "/X509/crl [lock:live-server]", test_crl, NULL, NULL, test_framework_skip_if_no_server_ssl); #endif #ifdef MONGOC_ENABLE_OCSP_OPENSSL diff --git a/src/libmongoc/tests/test-service-gcp.c b/src/libmongoc/tests/test-service-gcp.c index 724c00eace7..db634b92f71 100644 --- a/src/libmongoc/tests/test-service-gcp.c +++ b/src/libmongoc/tests/test-service-gcp.c @@ -107,5 +107,10 @@ test_service_gcp_install(TestSuite *suite) { TestSuite_Add(suite, "/gcp/http/parse", _test_gcp_parse); TestSuite_Add(suite, "/gcp/http/request", _test_gcp_http_request); - TestSuite_AddFull(suite, "/gcp/http/talk", _test_with_mock_server, NULL, NULL, have_mock_server_env); + TestSuite_AddFull(suite, + "/gcp/http/talk [uses:fake_kms_provider_server][lock:fake-kms]", + _test_with_mock_server, + NULL, + NULL, + have_mock_server_env); } diff --git a/tools/format.py b/tools/format.py index 4b2f75fff29..162697ce6e3 100644 --- a/tools/format.py +++ b/tools/format.py @@ -130,6 +130,7 @@ def main(argv: Sequence[str]) -> int: SOURCE_PATTERNS = [ '**/*.h', + '**/*.th', '**/*.hpp', '**/*.c', '**/*.cpp',